Giter Club home page Giter Club logo

mail-box-demo's Introduction

mail-box-demo

A local firm is building a small E-mail client to manage their internal messaging. You have been asked to implement a basic mailbox API in which the provided messages are listed. Each message can be marked as read and you can archive single messages.

How To Run

If you want to run it locally . You could you a docker compose & docker

Dockerized way

Now you have all that you need. So run from the root of the repo.

nash docker-compose up --build --force-recreate

It will build form scratch . 3 containers. WARN We use 8080 and 5432 ports. Make sure that ports are free

Wait a bit ....

Where to go

Local api: http://localhost:8080/api-docs/ We have embedded Swagger UI as a part of solution. All api related information could be found there . The good part of it you could try to run any endpoint and observe results and behaviors.

The secret

Ptsss !! Part of the task was a basic authentication. So we have a dynamic basic auth

  • user should start from oberlo + any string
  • password should start from cool42 + any string Sample request :
curl -u oberlo1:cool421 http://localhost:8080/api/messages

Architecture

The api

In a task it self we have a clear statement : Rest API with JSON format. It is really simplify a lot of decisions. REST is resource centric We have one recourse - message . We prefer manipulation over resource instead of action like api.

Requirement api endpoint sample url
List messages get messages curl -u oberlo1:cool421 http://localhost:8080/api/messages?limit=5
List archived messages get messages curl -u oberlo1:cool421 http://localhost:8080/api/messages?limit=5&q=archived
Show message get messages/id http://localhost:8080/api/message/5
Read message patch messages/id curl -u oberlo1:cool421 -X PATCH "http://localhost:8080/api/messages/5" -H "accept: application/json" -H "Content-Type: application/json" -d "{ "is_read": true}"
Archive message patch messages/id curl -u oberlo1:cool421 -X PATCH "http://localhost:8080/api/messages/5" -H "accept: application/json" -H "Content-Type: application/json" -d "{ "is_archived": true}"
- - -
Read & archive patch messages/id curl -u oberlo1:cool421 -X PATCH "http://localhost:8080/api/messages/5" -H "accept: application/json" -H "Content-Type: application/json" -d "{ "is_archived": true, "is_read": true}"
create message post messages curl -X POST "http://localhost:8080/api/messages" -H "accept: application/json" -H "authorization: Basic b29iZXJsbzE6Y29vbDQy" -H "Content-Type: application/json" -d "{ "sender": "stephen hawking", "subject": "the short history of time ", "message": "the history"}"

As you can see we have few bonus actions

  • I decide that with out create . API is incomplete.
  • path allow you to set read and archive fields together . As far as it is same partial update of resource.

One more note : I prefer to return Location header with a new/updated resource. It could save a lot of queries to db. If user really need a updated data . He could request it. Probably client that modify resource already know a future state only one key knowladge missed is a status of operation.

Operation statuses

status code
created 201
updated 200
not changed 304

Decisions

Server side Technologies

It is classical Express nodeJs based solution. On practise it is much faster an cheaper to use spring boot with spring but in this case we will not have so much to discus. Spring cover perfectly crud rest with db and when JOOQ is used you even will get keyset pagination out of the box. If you want something fast use a spring. So why i use node

  • Non blocking
  • no types - is bad but some times you could go faster . You dont need DTO or layer value transfer objects if you have structure of data that make you happy
  • JS is natural for me
  • fast api

API first

First that i did is a swagger file . I take a look to few cool project like openapi framework that allow you to create logic and glue with you swagger but all of this projects have a bit magic code generation. So I decide to still do a api first design but do not use a frameworks.

JSON & Validation

So as you know json and js object are brothers. It could give a big boost for api. I use declarative json schema for all request payload validation based on json schema. Less code more declarative way.

Project structure

class* use
handlers folks that process , request and generate response
service insulate a logic
convector map and transform request payload to internal structure
middleware standard express concept . Insulate reusable request processing parts
repo wrapper over db entity . allow to interact with storage
provider wrapper over pg pool . Hide complexity of DB communication
route map urls to handlers. glue all middleware and handlers

Storage

I see that data are well structured . So relational DB is a good candidate. It is easy to use and easy to find Devs.

ORM & migrations

Well . On long run you definitely need at list migration system. ORM - is overkill in our case , but it make a lot of manual work. Pls use you DB power and do not hide it.

Query builders

I decide not to use any of them . Down side - You need to define full query and only with template mechanisms that ofered by Db server. Good part - you Understand how it is working. It is transparent.

Export Task

see separate doc

pagination How To

Pagination

What next ....

It is not production ready !!

  • I omit all topics about SRE . retries . smart error handling etc .
  • It is not clustered . So entire solution is single thread. But service is stateless. So it could be clustered and balanced vie PM2 or etc
  • Environment configuration. DB connection is configured over a ENV variables. to make it flexible it much better to have env agnostic configs
  • Deployment
  • Migrations

Test

It is must have TDD or better BDD . I prefer spec level and e2e test . I have seen a lot 95% covered code but still a full of bugs. I prefer a pact integration test and one more docker with 'stimulator' that send a real request over scenario an then check result and compare dockerized DB. I still keen to do a popper tests. Dear reviewer . pls follow Integration Test PR

mail-box-demo's People

Contributors

volland avatar

Watchers

 avatar  avatar

mail-box-demo's Issues

Export task

As a Dev
I want to write an export task
So that export from json arbitrary file to db

Describe
To seed the database with some example messages there is a JSON file provided which needs to be imported into the database. Please write a task which can import this messages into the database.
messages_sample.json
Shared on Dropbox

{
  "messages": [
    {
      "uid": "21",
      "sender": "Ernest Hemingway",
      "subject": "animals",
      "message": "This is a tale about nihilism. The story is about a combative nuclear engineer who hates animals. It starts in a ghost town on a world of forbidden magic. The story begins with a legal dispute and ends with a holiday celebration.",
      "time_sent": 1459239867
    },
    {
      "uid": "22",
      "sender": "Stephen King",
      "subject": "adoration",
      "message": "The story is about a fire fighter, a naive bowman, a greedy fisherman, and a clerk who is constantly opposed by a heroine. It takes place in a small city. The critical element of the story is an adoration.",
      "time_sent": 1459248747
    },
    {
      "uid": "23",
      "sender": "Virgina Woolf",
      "subject": "debt",
      "message": "The story is about an obedient midwife and a graceful scuba diver who is in debt to a fence. It takes place in a magical part of our universe. The story ends with a funeral.",
      "time_sent": 1456767867
    },
    {
      "uid": "24",
      "sender": "George Orwell",
      "subject": "chemist",
      "message": "This is a tale about degeneracy. The story is about a chemist. It takes place in a manufacturing city. The story begins with growth.",
      "time_sent": 1456744407
    },
    {
      "uid": "25",
      "sender": "James Joyce",
      "subject": "nuclear engineer",
      "message": "The story is about an ugly nuclear engineer. It starts in a manufacturing city in Africa. The future of warfare is a major part of this story.",
      "time_sent": 1456733427
    },
    {
      "uid": "26",
      "sender": "Jane Austen",
      "subject": "treasure-hunter",
      "message": "The story is about a treasure-hunter and a treasure-hunter who is constantly annoyed by a misguided duke. It takes place on a forest planet in a galaxy-spanning commonwealth. The critical element of the story is a door being opened",
      "time_sent": 1456730427
    }
  ]
}

Pagination strategy

Acceptance

  • strategy desides
  • peflected in api
  • doc with explanation provided

Create api

As user
I want to have create message api
So that API has complete functionality

Description

Acceptance Criteria

  • tests

QA

Implement pagination get

As REPLACEME
I want REPLACEME
So that REPLACEME

FILL_ME_IN

Description

Acceptance Criteria

  • tests

QA

API Design

As a dev
I want to expose API as a swagger
So that it is publicly available

Message API
The main task is to build an API for the messages. It should to be a REST based API with a JSON formatted payloads.
The API should support the following use-cases.

  • List messages
    Retrieve a paginateable list of all messages. Show if messages were read already.
  • List archived messages
    Retrieve a paginateable list of all archived messages. Show if messages were read already.
  • Show message
    Retrieve message by id, include read status and if message is achived.
  • Read message
    This action “reads” a message and marks it as read in database.
  • Archive message
    This action sets a message to archived.

Acceptance

  • swager file describe api
  • service serve a swager as a docs

Sub tasks
#5 Open API

API security

As dev
I want to have a basic security middleware for API
So that it is accessible only by authorized users

Description

Acceptance Criteria
Use a basic Http autorisation

  • tests

QA

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.