Simple payments resource API complete with design, implementation, automation, live docs, live site, and development journal.
The final outputs, as specified by the brief, are:
Additional deliverables completed:
- Design docs hosted as Github Page
- Automation
- Dev journal
- Implementation Deployed to Heroku
- Swagger2PDF
The design directory contains the API design in swagger.json
format, as well as the resulting PDF as specified in the brief, a copy of the original payments payload example, some swagger2pdf config, and a Makefile to encapsulate the PDF generation.
The PDF, asciidoc, and HTML docs are all autogenerated from the payments.swagger.json
. This is done using an npm script
called regen-docs
in the root of the repository.
As mentioned above, the docs under the docs directory are autogenerated from the payments.swagger.json using an npm script
.
To run the generation yourself, clone the repo, cd to the root of it, and install the node_modules
via:
yarn # or `npm i` depending on your tool preference
Then run the script using:
yarn regen-docs # or `npm run regen-docs`
The docs dir now contains up-to-date HTML docs based on the payments.swagger.json, and the design dir contains up-to-date PDF and asciidocs.
The implementation directory contains the API implementation in golang. I used dep for dependency management because, in my experience, it is the most reliable dependency management system for golang and I didn't want to waste time fiddling with dependency versions.
The golang app is built, tested, and deployed using a multistage Dockerfile. The production stage of the image was initially FROM scratch
to be as small as possible but some minimal tooling was required in the image to have the container reliably testable, prod-test
and prod
stages are not a good idea because we should test exactly what runs in production, so the production image is based from alpine instead.
There are three docker-compose files:
- docker-compose.yml - used as a way of running the app locally. Consists of the app, and a postgres db.
- docker-compose.test.yml - used as a way of full-stack testing the app. Consists of a tester app. Should be merged with the regular docker-compose file by chaining
-f
specifications, e.g.docker-compose -f docker-compose.yml -f docker-compose.test.yml <command>
. Horrible, I know, but keeps the compose DRY. - docker-compose.test.hot.yml - same as above but with hot reloading on file change.
The following instructions assume you are in the implementation directory.
To build the app, generate the app
binary by running the make command:
make build
To build the docker image containing the production-ready app and its' test stage, run the make command:
make build-docker-image
The following instructions assume you are in the implementation directory.
Execute the unit test suite by running the make command:
make test
Execute the integration test suite by running the make command (requires having the app up and running separately, and a ready and willing postgres instance):
API_HOST=localhost API_PORT=8000 DB_HOST=postgres DB_PORT=5432 DB_USER=postgres DB_PASSWORD=postgres DB_NAME=payments make test-integration
Execute the acceptance test suite by running the make command (requires having the app up and running separately):
API_HOST=localhost API_PORT=8000 make test-acceptance
To execute all tests (unit, integration, acceptance), run the make command:
make docker-compose-test
To execute all tests (unit, integration, acceptance) in containers with hot reloading (rerun on file change), run the make command:
make docker-compose-test-hot
Success or failure can be seen in the logs output, and in the exit code returned by the command.
The following instructions assume you are in the implementation directory.
To run the app, first ensure you have a postgres instance running with a database created.
Set the database ENV variables as you run the make command:
DB_HOST=postgres DB_PORT=5432 DB_USER=postgres DB_PASSWORD=postgres DB_NAME=payments make test
OR
To run the app using docker-compose requires no database or environment setup on your part, simply run the make command:
make docker-compose-up
If the app started successfully, it will log a message indicating it's listening on a given port.
The port can be configured using the PORT
environment variable.