项目作者: danilojunS

项目描述 :
⚙️ Widgets SPA API
高级语言: Go
项目地址: git://github.com/danilojunS/widgets-spa-api.git
创建时间: 2017-08-08T07:16:51Z
项目社区:https://github.com/danilojunS/widgets-spa-api

开源协议:

下载


Widgets Single Page App API Build Status

My try on the backend API for the widgets-spa project! ✌️

Introduction

This is my implementation of the widgets-spa backend, written in Go.

This application basically consists on a CRUD for two concepts: users and widgets, exposed as an HTTP API authenticated via Token.

I tried to borrow some concepts from DDD (Doman Drive Design). Some of the concepts used here are:

  • entities: objects defined by its identity in the domain.
  • use cases: what the application does (their business purpose). The use cases could be discussed in an ubiquitous language with all tech and business stakeholders.

Thus, the project is organized in two main directories:

  • business: contains all business logic of the application. In this case, entities, use cases and repositories. A repository is the persistance layer for the entities and are an interface between the business and infra. Ideally, the code in the business layer could and should be discussed by all members (tech and business) in the organization, as they represent the domain business logic.
  • infra: contains all logic of how the application is accessed. In this case, it contains the code to start a server and create a connection with the database. This layer could be easily replaced by another one, as it does not contain any business logic. For example, the CRUD could be accessed by CLI tool, instead of an HTTP API.

For illustration, the flow of a request is:

  1. the request is routed to a handler (infra) of the server, which is responsible to call the appropriate use case.
  2. the use case receives parameters of the request and:
    1. instantiates the appropriate entities.
    2. validates the entitiy (business logic involved).
    3. calls the necessary services.
    4. processes the data and apply any business logic.
    5. persists the data, using a repository.
    6. returns result to handler.
  3. the handler receives the result from the use case, builds the response and send it to the client.

With the appropriate separation between the business and infra, we can build applications whose business logic can be re-used. Moreover, it promotes applications more aligned to their purpose in the organization, as both business and tech teams can discuss it and improve it more seamlessly. 🙌

The next sections describe how to install, run and test the application.

Installing and running

These steps assume that you have docker installed in your computer.

  1. Get the repository

    1. go get -v github.com/danilojunS/widgets-spa-api
  2. Go to the repository directory and run

    1. make docker-compose-start

    This command uses docker-compose to build and start two containers: one for the application (4000 port) and another for the database (5432 port).

  3. [optional] Populate the DB container with dummy data

    1. make docker-compose-db-populate

And that’s it! 👍

You can test the API in the url: http://localhost:4000 (view Try it section).

Without Docker

This steps assume that you have Go and Postgres installed and configured in your computer.

  1. Get the repository

    1. go get -v github.com/danilojunS/widgets-spa-api
  2. Install the dependencies

    1. make install
  3. Start the db

    1. pg_ctl -D /path/to/db/data -l logfile start
  4. [optional] Populate the DB (the command uses the default postgres database)

    1. make db-populate
  5. Start the application

    1. make start

Other usefull commands

All commands are declared and documented in the Makefile.

Some other useful commands (and their docker version) are:

  • make test or make docker-test

    Run the automated tests.

    The docker version of this command requires to run the make docker-build command first.

  • make watch or make docker-compose-watch

    Run the application in watch mode, that is, every change in the source codes will automatically restart your application.

Endpoints

This application exposes the following endpoints:

The 🔒 endpoints needs authentication using a token obtained in the GET /token endpoint.

The tokens must be passed in the Authorization header.

Eg.: Authorization: Bearer <TOKEN>

Try it" class="reference-link">Try it

After running it in you local machine, you can use this Postman Collection to easily try the API.

Run in Postman

Or use the good old curl:

  • Get token
    1. curl -X GET \
    2. http://localhost:4000/token
  • Get users
    1. curl -X GET \
    2. http://localhost:4000/users \
    3. -H 'authorization: Bearer <TOKEN>'
  • Get users/{id}
    1. curl -X GET \
    2. http://localhost:4000/users/1 \
    3. -H 'authorization: Bearer <TOKEN>'
  • Get widgets
    1. curl -X GET \
    2. http://localhost:4000/widgets \
    3. -H 'authorization: Bearer <TOKEN>'
  • Get widgets/{id}
    1. curl -X GET \
    2. http://localhost:4000/widgets/1 \
    3. -H 'authorization: Bearer <TOKEN>'
  • Create widgets
    1. curl -X POST \
    2. http://localhost:4000/widgets \
    3. -H 'authorization: Bearer <TOKEN>' \
    4. -H 'content-type: application/json' \
    5. -d '{
    6. "name": "My new widget",
    7. "color": "red",
    8. "price": "19.99",
    9. "inventory": 42,
    10. "melts": true
    11. }'
  • Update widgets
    1. curl -X PUT \
    2. http://localhost:4000/widgets/1 \
    3. -H 'authorization: Bearer <TOKEN>' \
    4. -H 'content-type: application/json' \
    5. -d '{
    6. "name": "My other widget",
    7. "color": "red",
    8. "price": "19.99",
    9. "inventory": 42,
    10. "melts": true
    11. }'

Improvements

Although this application was fun to build and test, there is still some improvements that could be done (implement end-to-end tests, increase test coverage, refactors to avoid repetition, etc).

Also, this was my first Go application 🙈
Some parts of the code are not as idiomatic as a seasoned Go programmer would write.

Please, feel free to open up an issue/PR if you feel like discussing these aspects!