/go-pay-me

Simple payments resource API complete with design, implementation, and development journal.

Primary LanguageGoMIT LicenseMIT

💸 Go-Pay-Me 💸 Travis (.org)

Simple payments resource API complete with design, implementation, automation, live docs, live site, and development journal.

Table of Contents 📚

Final Outputs 🥔

The final outputs, as specified by the brief, are:

Bonus 💎

Additional deliverables completed:

Design 💻

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.

Docs 📜

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.

Implementation 🏋️‍♂️

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.

Building 🏗️

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

Testing 🎭

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.

Running ⚡

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.