/address-book-api

Test project for hiring into STRV

Primary LanguageTypeScript

Address book API

Build Status Dependencies Test Coverage Maintainability Heroku

The address book backend will be used for registering new accounts and managing their contacts.

Application is running on Heroku.

Requirements

  • continuous integration (Travis/Heroku/Jenkins)
  • deploy (Heroku/AWS ECS/AWS EC2)
  • Node.js + Koa/Express
  • HTTP responses following best practices
  • JSON as data exchange
  • stateless authentication
  • user accounts stored in database
    • user signup/login
  • user contacts stored in Firebase
    • create new contact
  • tests
  • it's not needed to implement GET/UPDATE/DELETE

Development setup

There are several problems with Typescript+knex compatibility and Node+bcrypt version. Right now, working versions are:

  • knex@0.15.2 - issue
  • Node v10.12.0 + bcrypt@3.0.6 - info

Firebase credentials

Download firebase credentials (docs) and store it into address-book-api/src/config/service-account-file.json or on production server store it in environmental variable $FIREBASE_SERVICE_ACOUNT.

Usefull tools

VS Code

To have a convenient development in VS Code, following extensions with these settings are recommended:

  • ESLint
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        { "language": "typescript", "autoFix": true },
        { "language": "typescriptreact", "autoFix": true }
    ],
    "eslint.autoFixOnSave": true
  • Docker
  • GitLens
  • PostgreSQL - used for quick selects and checks for dockerized db
$ docker pull dpage/pgadmin4
$ docker run -p 80:80 \
    -e "PGADMIN_DEFAULT_EMAIL=user@domain.com" \
    -e "PGADMIN_DEFAULT_PASSWORD=SuperSecret" \
    -d dpage/pgadmin4

Postman

$ sudo snap install postman

Steps

$ cd address-book-api
$ docker-compose up -d
$ npm install

# Prepare json for root route
$ node make-build-info.js

$ # Code quality tools
$ npm run lint
$ npm run coverage

$ # Prepare database
$ npm run migrate

$ # Start development Typescript server with reloading after file change
$ npm run dev

$ # Start production server
$ npm run build
$ npm start

Example requests

Title URL Method Data params Success response code
Create user /users POST {email: [string], password: [string]} 201
Login user /session/user POST {email: [string], password: [string]} 201
Create contact /contacts POST {email: [string], name: [string], number: [string]} 201
Create user
$ # REQUEST
$ curl -X POST \
    https://strv-address-book-staruch-andr.herokuapp.com/users \
    -H 'Content-Type: application/json' \
    -H 'Postman-Token: 5c8dcc0d-8a6e-4788-8f18-d67d337a13f3' \
    -H 'cache-control: no-cache' \
    -d '{
        "email": "test@gmail.com",
        "password": "very strong password"
    }'

$ # RESPONSE
{
    "id": 3,
    "email": "test@gmail.com",
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjMsImlhdCI6MTU1NjgwODYyNCwiZXhwIjoxNTU2ODEyMjI0LCJpc3MiOiJjb20uaGVyb2t1YXBwLnN0cnYtYWRkcmVzcy1ib29rLXN0YXJ1Y2gtYW5kci5wcm9kdWN0aW9uIn0.GjC8dq6s6Q-fm0_gwG4jqmpx9-KAPQIk7fXnT7ReKbA"
}

Login user

$ # REQUEST
$ curl -X POST \
    https://strv-address-book-staruch-andr.herokuapp.com/session/user \
    -H 'Content-Type: application/json' \
    -H 'Postman-Token: 8d055b75-88d7-42e4-85a0-ae5210640ab5' \
    -H 'cache-control: no-cache' \
    -d '{
        "email": "test@gmail.com",
        "password": "very strong password"
    }'

$ # RESPONSE
{
    "id": 3,
    "email": "test@gmail.com",
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjMsImlhdCI6MTU1NjgwODg5MiwiZXhwIjoxNTU2ODEyNDkyLCJpc3MiOiJjb20uaGVyb2t1YXBwLnN0cnYtYWRkcmVzcy1ib29rLXN0YXJ1Y2gtYW5kci5wcm9kdWN0aW9uIn0.YHm2xGLXeIThD0MXMcMJy-OGIsaMsw5XHGpyvPLaOPw"
}

Create contact for logged user

$ # REQUEST
$ curl -X POST \
    https://strv-address-book-staruch-andr.herokuapp.com/contacts \
    -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjMsImlhdCI6MTU1NjgwODg5MiwiZXhwIjoxNTU2ODEyNDkyLCJpc3MiOiJjb20uaGVyb2t1YXBwLnN0cnYtYWRkcmVzcy1ib29rLXN0YXJ1Y2gtYW5kci5wcm9kdWN0aW9uIn0.YHm2xGLXeIThD0MXMcMJy-OGIsaMsw5XHGpyvPLaOPw' \
    -H 'Content-Type: application/json' \
    -H 'Postman-Token: 22bbd0cf-dde9-4523-a03e-4f8bb849b525' \
    -H 'cache-control: no-cache' \
    -d '{
        "number": "+421 903 123 456",
        "email": "some_other_email@yahoo.com",
        "name": "Jozko Mrkvicka"
    }'

$ # RESPONSE
{
    "-Ldt23-FWRXcwvjhZFVv": {
        "email": "some_other_email@yahoo.com",
        "name": "Jozko Mrkvicka",
        "number": "+421 903 123 456",
        "owner": 3
    }
}