golang-notes-api
Overview
API to manage user notes with
- Note Creation/Delete/Update
- User Register
- Note Archive/Unarchive
- Get notes for user
And featured with
- Inbuilt swagger ui for development mode
- golang pprof server
- pluggable transport (http is only implemented currently)
- prometheus metrics (only default go metrics available currently)
- JWT certificate generation command
API Usage
APIs
When the transport.httpTransport.swaggerEnabled is enabled API will expose swagger UI under :8080/swageer/index.html
Authentication
HTTP API uses JWT Token based authentication. Token can be generated using auth/login and need to send the token as the Authorization Bearer token
Pre requisits
For build & run
- Go 1.17
- MySQL 5.7
- RSA Keygen see
For testing
For quick start
Quick start
To get start using the API quickly, just run
docker-compose up
API will be available at http://0.0.0.0:8080/api
Swagger will be available at http://0.0.0.0:8080/swagger/index.html
Configurations
API suports config file injection at the startup and supports ENV variable config overriding. Default config file located at the configs dir. application can start by providing the config file. config file path can be absolute and relative
./golang-notes-api run -c configs/config.example.yaml
Any value in injecting config file can be replaced by env variables, for example by setting the CONF_DB_CONNECTIONSTRING env variable will replace the DB.ConnectionString value in the conf file. It is a best practice to have sensitive configurations like db string, in an env variable
CONF_DB_CONNECTIONSTRING=secure_db_conn_string ./golang-notes-api print-config -c configs/config.example.yaml
db setup
MySQL db is supported currenlty
To setup the initial db schema use script in scripts/db/DB_MySQL_Table_Create.sql
JWT Key generation
To sign the JWT tokens API uses RS256 Algorithm. So it needs the RSA public/private key pair to sign/validate the tokens
Using keygen command app will create a new key pair
Commands
version prints the app version
print-config print the current active config
keygen create a new private/public keypair for JWT signing in configs/jwt_key dir
run start the api server
Swagger
API has inbuilt swagger UI, which will be available through httpTransport port under http://0.0.0.0:8080/swagger/index.html url if the swagger enabled from the config transport.httpTransport.swaggerEnabled
Docs dir contains the swagger files that can be used in any swagger editor. This swagger will be automatically generated from the annotations in the code. To regenerate the swagger specs run swagger init command, swag must be installed in the system. https://github.com/swaggo/swag
swag init -g internal/app/transport/http/server.go
Add access token in the swagger using Authorize buttin and et the token as
'Bearer [access token taken from login end point]'
Binary build
go build
Start the binary
To run the API create the DB schema, and change the configurations accordingly
API can be run in two ways, from go run or build the binary and run the binary
Using Go run
go run main.go run -c configs/config.example.yaml
Using build binary
go build
./golang-notes-api run -c configs/config.example.yaml
Test running
go test ./...
Choice of Technology
For this API implementation I decided to go with the golang because it is very robust and im quite familiar with it
I decided to go with Clean Architecture https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html as it promotes the separations of frameworks with business logics. The project is structured with concidering the both guidelines from Clean Architecture and the Go Project structure guidelines https://github.com/golang-standards/project-layout. Project is structured in such a way that the transport technology is completely independent with the business logic. For example if we want to add the gRPC support, just add the transport layer to the app/transport. No changes are needed to do in the business layer (usecases)
App has the ability to export the prometheus metrics, so that monitoring like grafana can be integrated. And also app will expose the golang pprof server port to support remote debugging. Both pprof port and the metrics will be served in a different tcp port so that those endpoints can be keep in internal networks in production environments.
I decided to go with the MySQL as the database. But repository layer is completely decoupled with the usecases.
Docker compose is used to spin up App for the quickly without setting up the Databases, Go SDK. Developer can run the app by just running the docker-compose up
Further Work
- User password reset
- Get all notes with pagination, pagination support
- Admin api to activate/deactivate/delete user
- Custom prometheus metrics (api-requests, response-codes, logins, failed-logins, db-metrics, ..etc )
- Health check probes (so that load balancers, reverse proxy, kubernetes can know the status of the backend)
- DB layer transactions