All Projects โ†’ pagarme โ†’ Superbowleto

pagarme / Superbowleto

Licence: mit
๐Ÿˆ A microservice to issue, register and manage boletos

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Superbowleto

Typescript Rest
This is a lightweight annotation-based expressjs extension for typescript.
Stars: โœญ 458 (-17.48%)
Mutual labels:  microservice
Webiny Js
Enterprise open-source serverless CMS. Includes a headless CMS, page builder, form builder and file manager. Easy to customize and expand. Deploys to AWS.
Stars: โœญ 4,869 (+777.3%)
Mutual labels:  microservice
Getty
a netty like asynchronous network I/O library based on tcp/udp/websocket; a bidirectional RPC framework based on JSON/Protobuf; a microservice framework based on zookeeper/etcd
Stars: โœญ 532 (-4.14%)
Mutual labels:  microservice
Gearbox
Gearbox โš™๏ธ is a web framework written in Go with a focus on high performance
Stars: โœญ 455 (-18.02%)
Mutual labels:  microservice
Microservices
Microservices from Design to Deployment ไธญๆ–‡็‰ˆ ใ€ŠๅพฎๆœๅŠก๏ผšไปŽ่ฎพ่ฎกๅˆฐ้ƒจ็ฝฒใ€‹
Stars: โœญ 4,637 (+735.5%)
Mutual labels:  microservice
Sca Best Practice
ๆœฌ้กน็›ฎๆ˜ฏ SCA(Spring Cloud Alibaba) ๅฎ˜ๆ–น็š„ๆœ€ไฝณๅฎž่ทต้กน็›ฎ๏ผŒ่‡ดๅŠ›ไบŽๅธฎๅŠฉ็”จๆˆทๆ›ดๅŠ ๅฟซ้€Ÿใ€ๆญฃ็กฎ็š„ไฝฟ็”จSCAใ€‚
Stars: โœญ 496 (-10.63%)
Mutual labels:  microservice
Kubernetes Handbook
Kubernetes Handbook ๏ผˆKubernetesๆŒ‡ๅ—๏ผ‰ https://kubernetes.feisky.xyz
Stars: โœญ 4,511 (+712.79%)
Mutual labels:  microservice
Chatengine
Open source mtproto server written in golang with compatible telegram client
Stars: โœญ 544 (-1.98%)
Mutual labels:  microservice
Cppmicroservices
An OSGi-like C++ dynamic module system and service registry
Stars: โœญ 482 (-13.15%)
Mutual labels:  microservice
Kapow
Kapow! If you can script it, you can HTTP it.
Stars: โœญ 526 (-5.23%)
Mutual labels:  microservice
Imgproxy
Fast and secure standalone server for resizing and converting remote images
Stars: โœญ 5,688 (+924.86%)
Mutual labels:  microservice
Besticon
Favicon service written in Go
Stars: โœญ 472 (-14.95%)
Mutual labels:  microservice
Cap
Distributed transaction solution in micro-service base on eventually consistency, also an eventbus with Outbox pattern
Stars: โœญ 5,208 (+838.38%)
Mutual labels:  microservice
Paseto
Platform-Agnostic Security Tokens implementation in GO (Golang)
Stars: โœญ 461 (-16.94%)
Mutual labels:  microservice
Awesome Fenix
่ฎจ่ฎบๅฆ‚ไฝ•ๆž„็ญ‘ไธ€ๅฅ—ๅฏ้ ็š„ๅˆ†ๅธƒๅผๅคงๅž‹่ฝฏไปถ็ณป็ปŸ
Stars: โœญ 530 (-4.5%)
Mutual labels:  microservice
Camelinaction2
๐Ÿซ This project hosts the source code for the examples of the Camel in Action 2nd ed book ๐Ÿ“• written by Claus Ibsen and Jonathan Anstey.
Stars: โœญ 453 (-18.38%)
Mutual labels:  microservice
Mortar
Mortar is a GO framework/library for building gRPC (and REST) web services.
Stars: โœญ 492 (-11.35%)
Mutual labels:  microservice
Ops
ops - build and run nanos unikernels
Stars: โœญ 552 (-0.54%)
Mutual labels:  microservice
Python Flask Microservice
Skeleton of a Microservice built with the Flask
Stars: โœญ 544 (-1.98%)
Mutual labels:  microservice
Javalin
A simple and modern Java and Kotlin web framework
Stars: โœญ 5,184 (+834.05%)
Mutual labels:  microservice

superbowleto

Build Status

๐Ÿˆ A microservice to issue, register and manage boletos

Table of Contents

Technology

Here's a brief overview of our technology stack:

  • Docker and Docker Compose to create our development and test environments.
  • AWS Fargate to manage and deploy our containers.
  • AWS SQS as a queue manager to process things like boletos to register and SQS Quooler as a package to make the interaction with queues more easy.
  • Postgres as to store our data and Sequelize as a Node.js ORM.
  • Ava as a test runner and Chai to do some more advanced test assertions.
  • Express as a tool to build the web server that handles our boleto endpoints.

Developing

In order to develop for this project you must have Docker and Docker Compose installed.

First Install

If you never developed in this repo before:

  1. Clone the repository:
$ git clone [email protected]:pagarme/superbowleto
  1. Build the base images:
$ docker-compose build superbowleto-web

Running the server

To run the server, you will have to start the database and run the migrations.

  1. Start database and run migrations in one command:
$ make setup-db
  1. Or start database and run migrations separately:
  • Start database (postgres):

    $ make start-db
    
  • Run the migrations:

    $ make migrate
    
  1. Then finally run the server:
$ make superbowleto-web

Running tests

Tests are separate in functional, integration and unit. You can either run them separately or run them all.

  • Run all tests:

    $ docker-compose run test
    
  • Run only functional tests:

    $ docker-compose run test npm run test-functional
    
  • Run only integration tests:

    $ docker-compose run test npm run test-integration
    
  • Run only unit tests:

    $ docker-compose run test npm run test-unit
    

For the CI purposes we have a specif command that will generate coverage report and xml test results report to be published at the CircleCI.

$ docker-compose run --entrypoint="npm run test-ci" test --abort-on-container-exit

Installing new dependencies

We install our dependencies (aka npm dependencies) inside the Docker image (see our Dockerfile to understand it better).

This gives us the advantage of caching the dependencies installation process, so when we build the image again, it's already cached by Docker and the image can be easily distributed with all its dependencies installed.

However, if you need to install any new dependency, you must rebuild the image, otherwise, your dependency will not be available inside the container.

You can install dependencies and rebuild the image by running:

$ docker-compose run test npm install --save ramda
$ docker-compose build test

Testing

Tests are found inside the test/ directory and are separate by type: functional, integration and unit. It's also common to have some helpers folders alongside the tests.

  • Unit tests are used to test the smallest units of functionality, typically a method or a function ref.

    The folder structure of the unit tests tend to mirror the folder structure of the src folder. For instance, we generally see the following folder structure:

    โ”œโ”€โ”€ src
    โ”‚   โ”œโ”€โ”€ index.js
    โ”‚   โ””โ”€โ”€ lib
    โ”‚       โ””โ”€โ”€ http.js
    โ””โ”€โ”€ test
        โ””โ”€โ”€ unit
            โ”œโ”€โ”€ index.js
            โ””โ”€โ”€ lib
                โ””โ”€โ”€ http.js
    
  • Integration tests build on unit tests by combining the units of code and testing that the resulting combination functions correctlyref.

    The folder structure of the integration tests tend to mirror the folder structure of the src folder. For instance, we generally see the following folder structure:

    โ”œโ”€โ”€ src
    โ”‚   โ”œโ”€โ”€ index.js
    โ”‚   โ””โ”€โ”€ lib
    โ”‚       โ””โ”€โ”€ http.js
    โ””โ”€โ”€ test
        โ””โ”€โ”€ integration
            โ”œโ”€โ”€ index.js
            โ””โ”€โ”€ lib
                โ””โ”€โ”€ http.js
    
  • Functional tests check a particular feature for correctness by comparing the results for a given input against the specification. Functional tests don't concern themselves with intermediate results or side-effects, just the resultref.

    The folder structure of functional tests does not need to mirror the source folder, and the files can be organized as they seem fit. One way to organize this files is by feature or user-story. For instance, take a look at the example below, where boleto/create.js and boleto/register.js are complete user stories:

    โ”œโ”€โ”€ test
        โ””โ”€โ”€ functional
            โ””โ”€โ”€ boleto
                โ””โ”€โ”€ create.js
                โ””โ”€โ”€ register.js
    
  • Helpers do not test anything, but instead provide tools for the tests. Inside the helpers folders one can have fixtures (also know as "mocks"), or some util functions.

    For instance, if you need credit card information to perform various tests in many different places, or if you need an util function that is called before your tests are ran, you could place them inside a helpers folder in order to not repeat yourself:

    const creditCardMock = {
      number: 4242424242424242,
      holder_name: 'David Bowie',
      expiration_date: 1220,
      cvv: 123,
    }
    
    const cleanUpBeforeTests = () => {
      db.reset()
    }
    
    module.exports = {
      creditCardMock,
      cleanUpBeforeTests,
    }
    

    Helpers folders can be created at any level within the test folder structure. If some helper is used only for unit tests, it should reside within test/unit/helpers. If the helpers is used across all tests, it should reside within test/helpers. If there's a helper that is used only for testing the http module on integration tests, then it should reside within test/integration/http/helpers.

Data Flow

This project has two programs, the worker and the server.

Server

This section documents what every endpoint of the server does.

1. POST /boletos

Create a new boleto.

After creating the boleto (on our database), we will try to register the boleto withing the provider. Here, there's two possible outcomes: a) the provider could be reached, could process the boleto and gave us a status (either registered or refused); or b) the provider could not be reached or could not process the boleto (giving us an unknown/undefined/try_later status).

a) Provider could process the boleto

The following steps illustrate the case where the provider could be reached and it could process the boleto.

  1. The Client makes an HTTP request to create a boleto.
  2. We create the boleto in the Database with status issued.
  3. We try to register the boleto within the Provider.
  4. The provider returns an answer (either registered or refused).
  5. We update the boleto status in the Database.
  6. We return the response to the Client (HTTP response).

1a-post-boletos-diagram

Diagram built with mermaid.js. Check out the source code at docs/diagrams/server

b) Provider could not process the boleto

The following steps illustrate the case where the provider could be reached and it could process the boleto.

  1. The Client makes an HTTP request to create a boleto.
  2. We create the boleto in the Database with status issued.
  3. We try to register the boleto within the Provider.
  4. The provider could not be reached or could not process the boleto.
  5. We update the boleto status in the Database to pending_registration.
  6. We send the boleto (boleto_id and issuer) to an SQS queue called boletos-to-register. This queue will be processed by the worker later.
  7. We return the response to the Client (HTTP response) with the status = pending_registration.

1b-post-boletos-diagram

Diagram built with mermaid.js. Check out the source code at docs/diagrams/server

Example:

POST /boletos

Content-Type: application/json

{
  "queue_url": "http://yopa/queue/test",
  "expiration_date": "Tue Apr 18 2017 18:46:59 GMT-0300 (-03)",
  "amount": 2000,
  "instructions": "Please do not accept after expiration_date",
  "issuer": "bradesco",
  "payer_name": "David Bowie",
  "payer_document_type": "cpf",
  "payer_document_number": "98154524872"
}

201 Created

Content-Type: application/json

{
  "queue_url": "http://yopa/queue/test",
  "status": "issued | registered | refused",
  "expiration_date": "Tue Apr 18 2017 18:46:59 GMT-0300 (-03)",
  "amount": 2000,
  "instructions": "Please do not accept after expiration_date",
  "issuer": "bradesco",
  "issuer_id": null,
  "title_id": "null",
  "payer_name": "David Bowie",
  "payer_document_type": "cpf",
  "payer_document_number": "98154524872"
}

2. GET /boletos

Retrieve all boletos.

2-get-boletos-diagram

Diagram built with mermaid.js. Check out the source code at docs/diagrams/server

Example:

GET /boletos

Content-Type: application/json

{
  "count": "10",
  "page": "1"
}

200 Ok

Content-Type: application/json

[{
  "id": "bol_cj1o33xuu000001qkfmlc6m5c",
  "status": "issued",
  "queue_url": "http://yopa/queue/test",
  "expiration_date": "Tue Apr 18 2017 18:46:59 GMT-0300 (-03)",
  "amount": 2000,
  "instructions": "Please do not accept after expiration_date",
  "issuer": "bradesco",
  "issuer_id": null,
  "title_id": "null",
  "payer_name": "David Bowie",
  "payer_document_type": "cpf",
  "payer_document_number": "98154524872"
}]

3. GET /boletos/:id

Find one boleto by id.

3-get-boletos-id-diagram

Diagram built with mermaid.js. Check out the source code at docs/diagrams/server

Example:

GET /boletos/:id

Content-Type: application/json

{
  "id": "bol_cj1o33xuu000001qkfmlc6m5c"
}

200 Ok

Content-Type: application/json

{
  "id": "bol_cj1o33xuu000001qkfmlc6m5c",
  "status": "issued",
  "queue_url": "http://yopa/queue/test",
  "expiration_date": "Tue Apr 18 2017 18:46:59 GMT-0300 (-03)",
  "amount": 2000,
  "instructions": "Please do not accept after expiration_date",
  "issuer": "bradesco",
  "issuer_id": null,
  "title_id": "null",
  "payer_name": "David Bowie",
  "payer_document_type": "cpf",
  "payer_document_number": "98154524872"
}

Worker

This section documents what the worker processes.

1. Process boletos-to-register queue

This is a worker which consumes the queue which has boletos to register and effectively register them.

When a boleto can't be registered within the provider at the moment of its creation, it will be posted to a SQS Queue called boletos-to-register. This worker is responsible for processing this queue. Here are the steps:

  1. This worker consumer function is triggered when an item is on the queue
  2. Using sqs-quooler we then start to poll items from SQS (sqs.receiveMessage)
  3. Each message received has a boleto ({ id, issuer}) and a message (the raw SQS message from boletos-to-register queue).
  4. We use the boleto id to find the boleto on Database.
  5. We check if the boleto can be registered, i.e. if the status of the boleto is either issued or pending_registration.
  6. If the boleto can be registered, we try to register it within the provider.
  7. If the provider could not process the boleto, we stop executing here. The SQS Message will then go back to boletos-to-register queue and will be later processed.
  8. We update the boleto status with either registered or refused.
  9. IMPORTANT: After the boleto is updated, we notify the boleto owner by sendin an SQS message to the queue the owner specified on the boleto creation (aka: boleto.queue_url). The owner will then handle the processing of these SQS Messages. That's the only way we can notify the boleto owner that a boleto that went to boletos-to-register queue was updated. That's why it's mandatory to pass a queue at the moment of the boleto creation. 1-process-boletos-to-register-queue-diagram

Diagram built with mermaid.js. Check out the source code at docs/diagrams/worker

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].