go-api

command module
v0.0.0-...-37234c6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 24, 2022 License: MIT Imports: 16 Imported by: 0

README

Product and subscription API

Go REST API with GORM ORM (POSTGRESQL), Mux and JWT

Installation

To simplify the installation process, there is a dev docker file and a docker compose file that can be used to run the project locally, so the only dependency is a running Docker installation
Once the Docker client is running, use the following command:

docker-compose up

Please note that the build described in docker-compose.yml file is purely a dev tool. We are running air to have a hot reload API that monitors the code and rebuilds on the go.

NOTE: If you are using Windows you might run into issues with the hot reload because of how virtualization works on Windows (it is a WSL2 limitation, documented here)

Dockerization

On startup, Docker creates three containers, one for the actual API, one for Postgres and an additional container for PGAdmin4 (this is really useful for development and for general DB monitoring). In general you fill find this:

Container Purpose Local port
API Hosting the Go app 8080
Postgresql Database system 5432
PgAdmin4 Database UI Navigator 5050

The .env

For development purposes I have setup a .env file on the root of the folder It contains the database credentials and also the pgAdmin credentials, you can log in into PgAdmin on your browser by visiting http://localhost:5050/browser/

Endpoints and API

To make the testing process easier, I created a Postman Collection and Environment. They are located at the root of the project on go-api.postman_collection.json and go-api-test.postman_environment.json respectively. Please import them into Postman to be able to check the endpoints smoothly.

Auth

To actually authenticate requests, I created two endpoints /auth/register where you can create your user like this:

curl --location --request POST 'http://localhost:8080/auth/register' \
--header 'Content-Type: application/json' \
--data-raw '{
    "username": "juan",
    "password": "admin123"
}'

And to actually authenticate requests we are using JWT, so to get a new token, use the auth/token endpoint with your newly created user, like this:

curl --location --request POST 'http://localhost:8080/auth/token' \
--header 'Content-Type: application/json' \
--data-raw '{
    "username": "juan",
    "password": "admin123"
}'

That should be it. You now have a bearer token ready to authenticate all your requests to the API.

The rest of the endpoints are located on api/..., please remember to always send your bearer token with your request, or you will get rejected by the API:

curl --location --request GET 'http://localhost:8080/api/products' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRob3JpemVkIjp0cnVlLCJleHAiOjE2NDU2ODYyMjUsInVzZXJfaWQiOjJ9.n-RRL1rKCfXaFAV8-4R53o63rFzBnQI--Akbm2d3lDk'

Project structure

go-api
├─ .air.toml
├─ .env
├─ .gitignore
├─ docker-compose.yml
├─ Dockerfile
├─ go-api-test.postman_environment.json
├─ go-api.postman_collection.json
├─ go.mod
├─ go.sum
├─ init.sql
├─ LICENSE
├─ main.go
├─ pkg
│  ├─ api
│  │  ├─ middleware
│  │  │  ├─ auth.go
│  │  │  └─ logs.go
│  │  └─ service
│  │     ├─ products
│  │     │  ├─ repository.go
│  │     │  └─ service.go
│  │     ├─ subscriptions
│  │     │  ├─ repository.go
│  │     │  └─ service.go
│  │     ├─ user
│  │     │  ├─ repository.go
│  │     │  └─ service.go
│  │     └─ voucher
│  │        └─ repository.go
│  ├─ auth
│  │  ├─ jwt.go
│  │  └─ passwords.go
│  ├─ migrations
│  │  └─ automigrate.go
│  ├─ models
│  │  ├─ products.go
│  │  ├─ shared
│  │  │  ├─ pagination.go
│  │  │  └─ query.go
│  │  ├─ subscription.go
│  │  ├─ users.go
│  │  └─ voucher.go
│  └─ shared
│     └─ utils
│        ├─ queryParser.go
│        └─ writeError.go
└─ README.md

The project was setup using a Microservice oriented structure, we have interface defined repositories and services for all entities that register routes with a central mux Router. I also include Middleware to actually get the user id from the bearer token and another one to log the request to stout. Because all repos and services are defined as interfaces they are highly testable both on the unit level and on the service integration level. You could spin up a server with mocked repositories to test all services end to end. Unfortunately, I did not have enough time to add unit tests to the project :(

I hope you have as much fun reviewing the challenge as I had building it :)

License

MIT

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL