1.8.1 • Published 5 years ago

techubank-api v1.8.1

Weekly downloads
1
License
ISC
Repository
bitbucket
Last release
5 years ago

Introduction

TechU Bank rest API server allows the Techubank Front to operate with Techubank.

Entities managed by the API:

  • User
  • Accounts
  • Transfers
  • Movements

API Rest Documentation

The API documentation is written following the Open API v2 specification in a Swagger YAML file.

You can find all the specification versions in ws-doc folder. It's automatically rendered using swagger-ui library.

In localhost you can check the documentation and try any endpoint:

1) Start the nodejs server

techu@techu> npm install \
				npm run start

2) Access the ws-doc link|http://localhost:3000/ws-doc 3) You will be able to test the endpoints setting the apki-key variable with the value "test"

Requirements

This project needs:

  • Nodejs 8.4+
  • Docker 17+ if you want to publish a new docker image or run the latest TechU Bank docker image

Environment variables

This API is securized via OAuth2 method; by default it is setup our own OAuth 2 Server.

techubank-api orchestate calls to techubank-mlab. techubank-mlab is the component which interact with MongoDB; and that connectivity is securized too. You have to facilitate the username and password of an admin user (by default techubank / techubank1234).

Create a .env file on the base path with the following variables

API_USERNAME=<username-with-admin-scope>
API_PASSWORD=<password>

Folders

  • bin: helpers - pre-commit: execute linter and unit tests before a commit - swagger-codegen.sh: parse swagger.vX.yaml and generates an api-client and a scaffold for the server side.
  • src: The API logic
  • test: unit tests folder
  • ws-doc: assets for rendering swagger in a friendly way

Compilation

Stay on the base path where package.json is located.

techu@techu> npm install

Unit tests

1) Stay on the base path where package.json is located.

techu@techu> npm run test

2) If you want to execute unit tests on each change, execute the watcher command.

techu@techu> npm run watcher

3) To get coverage metrics run Instanbul

techu@techu> npm run coverage

Static code analysis

Linter

Linter is a light weight static code analysis recomended to be execute in every push to a branch, and may block the push.

techu@techu> npm run lint

Sonarqube - sonar-scanner Docker image

We have prepared a container with the software enough for run a static code analysis, execute unit tests, measure unit test coverage and upload the results to Sonarqube (free account).

You must have a Sonarqube API Key, configure properly the sonar-scanner.properties and run the command below:

$ docker run -it --env SONAR_API_KEY=<SONAR_USER_API_KEY> --mount type=bind,source="$(pwd)",target=/root/project -v "$(pwd)"/sonar-scanner.properties:/root/sonar-scanner/conf/sonar-scanner.properties davidrova/sonar-scanner:latest

To see the result click on this link.

The evaluation period has expired and we cannot upload more executions.

Don't worry, you can still perform static code analysis, but following a couple of additional steps.

Sonarqube - sonar Docker image

1) Launch a sonarqube instance (admin / admin)

$ docker run -d -p 9000:9000 -p 9092:9092 sonarqube

2) Generate a new API-KEY

3) Download sonar-scanner in localhost or use sonar-scanner Docker image sonar-scanner documentation

4) Run unit tests and coverage

$ npm run test
$ npm run coverage

5) Run sonar-scanner; sonar-scanner loads sonar-project.properties file

$ SONAR_API_KEY=<SONAR_API_KEY> sonar-scanner

6) View the results in Sonarqube

Hooks

We encourage to enable the pre-commit hook. It will avoid commiting a change if linter or unit tests fail.

techu@techu> cp bin/pre-commit .git/hooks/pre-commit

Continuous integration

The project is managed in bitbucket.org and we have automated an ease pipeline with the following step rules:

  • A commint into develop branch triggers: - build - Increases the patch version - Publish the artifact to npmrc registry - Publish a new docker image into Docker Hub
  • A commit into master branch triggers: - build - lint - unit tests - Increases the minor version - Publish the artifact to npmrc registry - Publish a new docker image into Docker Hub

Important settings tips

In order to be able to execute git commands against our repository, it is neccessary to give grants to the pipeline; it's neccessary to generate a new key pair. Follow these instructions

TechU Bank Docker image

Our images have been built with DOCKER_HUB_USERNAME=davidrova.

Start TechU Bank docker image (HTTP/HTTPS)

docker run -p 3000:3000 -p 3443:3443 -e API_USERNAME=<admin-username> -e API_PASSWORD=<admin-password> --name techubank__testing ${DOCKER_HUB_USERNAME}/techubank-api

Stop TechU Bank docker image

docker stop techubank__testing

Remove TechU Bank docker image

docker rm techubank__testing

Building and push the docker image

docker build -t ${DOCKER_HUB_USERNAME}/techubank-api .
docker login --username=${DOCKER_HUB_USERNAME} --password=${DOCKER_HUB_PASSWORD}
docker push ${DOCKER_HUB_USERNAME}/techubank-api 

Architecture details

Techubank-api starts an express instance supporting http and https protocols. The component is splitted in the following pieces:

  • index.js: where the express process is launched - Fetch the environment variables depending the environment (localhost, docker, kubernetes, pro) - Enable public access to the swagger documentation via swagger-ui - Enable the different endpoints to the main entities managed by the API, pointing to each router
  • router:
    - Checks security headers, using the common utility from techubank-commons check-security-headers; not all the endpoints are secured, so check swagger documentation and check if the endpoint is secured. - Enable/disable cors depending the environment - Link each endpoint with its correspondent entity's controller
  • controller: it really implements the logic - Each controller must operate with techubank-mlab or techubank-auth-server. These operations are secured, and needs an admin user to operate.
    - Admin user is passed as enviornment variable in a .env file with the names API_USERNAME and API_PASSWORD - techubank-api users have the credentials with user grants, but techubank-api needs to take that request, and execute a logic with the backend using its own credentials (admin credentials)

That is a big picture about how the API server is working. It's interesting to notice a couple of helpers implemented to control better the code. All these helpers are centralized in the piece techubank-commons.

Controller

Controllers excapsulate the logic called from the router. Router is configured with the function reference, and there is no choice to pass it the context (this). This is the reason why we have decided to expose static methods to the router and implement a controlled logic inside.

Let's explain it with UserController class.

1) What we have in the router

user_router.get('/:username/info', UserController.getUserByUsername)

2) Define the static method which implements the logic

We create a user_controller object, load "admin" credentials and call the real logic.
module.exports = class UserController extends BaseController {
    constructor() {
        super()
    }

	// method exposed to the router
    static getUserByUsername(req, res) {
        const user_controller = new UserController()

        return user_controller.load_token().then(() => {
            return user_controller._getUserByUsername(req, res)
        })
    }

3) Function body implementation focused to enable unit testing

We have encapsulated calls to the backend as an instance's function to be able to mock it easily using Sinon.js (client_get, client_post, client_put). These functions returns a Promise. With the resolution of the Promise we act as neccessary.

When the Promises resolves then we control the response.statusCode and call the accurate function (passing the context with call).

    /**
     * The username is in the request req.params['username']
     * 
     * @param {object} req 
     * @param {object} res 
     */
    _getUserByUsername(req, res) {
        logger.info(`Fetch user ${req.params.username}`)

        return this.client_get(`/v1/user/${req.params.username}/info`).then((res_post_mlab) => {
            return this.request_handler.call(this, res_post_mlab, {
                success_handler: this._getUser_success_handler,
                error_handler: this._getUser_error_handler,
                unauthorized_handler: this._getUser_error_handler
            }, res)
        })
    }

4) How we replace backend calls with Sinon.js

With Sinon.js it's very easy to isolate our piece from dependencies; but you must considere one constraint; the function to replace must be a instance's function.

const user = new UserController()

const callback = sinon.stub(user, 'client_get')
callback.returns(new Promise((resolve) => {
	return resolve({
		statusCode: 200,
		body: JSON.stringify(require('../resources/user')),
		send: (data) => {
			return data
		}
	})
}))

techubank-commons' helpers

It is recomended to check if there is a new techubank-commons release.

$ npm update

To import the helpers

    {
        environment,
        logger,
        http_request_handler,
        propagate_error_response,
        get_admin_token
    } = require('techubank-commons')

Further information about techubank-commons click on the link

1.8.1

5 years ago

1.1.14

5 years ago

1.8.0

5 years ago

1.1.13

5 years ago

1.1.12

5 years ago

1.1.11

5 years ago

1.7.0

5 years ago

1.1.10

5 years ago

1.6.0

5 years ago

1.1.9

5 years ago

1.1.8

5 years ago

1.1.7

5 years ago

1.1.6

5 years ago

1.1.5

5 years ago

1.1.4

5 years ago

1.5.0

5 years ago

1.1.3

5 years ago

1.4.0

5 years ago

1.1.2

5 years ago

1.1.1

5 years ago

1.2.0

5 years ago

1.1.0

5 years ago

1.0.94

5 years ago

1.0.93

5 years ago

1.0.92

5 years ago

1.0.91

5 years ago

1.0.90

5 years ago

1.0.89

5 years ago

1.0.88

5 years ago

1.0.87

5 years ago

1.0.86

5 years ago

1.0.85

5 years ago

1.0.84

5 years ago

1.0.83

5 years ago

1.0.82

5 years ago

1.0.81

5 years ago

1.0.80

5 years ago

1.0.79

5 years ago

1.0.78

5 years ago

1.0.77

5 years ago

1.0.76

5 years ago

1.0.75

5 years ago

1.0.74

5 years ago

1.0.73

5 years ago

1.0.72

5 years ago

1.0.71

5 years ago

1.0.70

5 years ago

1.0.69

5 years ago

1.0.68

5 years ago

1.0.67

5 years ago

1.0.66

5 years ago

1.0.65

5 years ago

1.0.64

5 years ago

1.0.63

5 years ago

1.0.62

5 years ago

1.0.61

5 years ago

1.0.60

5 years ago

1.0.59

5 years ago

1.0.58

5 years ago

1.0.57

5 years ago

1.0.56

5 years ago

1.0.55

5 years ago

1.0.54

5 years ago

1.0.53

6 years ago

1.0.52

6 years ago

1.0.51

6 years ago

1.0.50

6 years ago

1.0.49

6 years ago

1.0.48

6 years ago

1.0.47

6 years ago

1.0.46

6 years ago

1.0.45

6 years ago

1.0.44

6 years ago

1.0.43

6 years ago

1.0.42

6 years ago

1.0.41

6 years ago

1.0.40

6 years ago

1.0.39

6 years ago

1.0.38

6 years ago

1.0.37

6 years ago

1.0.36

6 years ago

1.0.34

6 years ago