|
1 |
| -# gomin |
| 1 | +# Example Go Rest API with a PostgreSQL database |
| 2 | + |
| 3 | +This repository demonstrates how to fully wire up and deploy a Golang REST API with a PostgreSQL database backend. |
| 4 | + |
| 5 | +The application demonstrates: |
| 6 | + |
| 7 | +- `REST API` using [Echo](https://echo.labstack.com/) |
| 8 | +- `PostgreSQL integration` using [PGX](https://github.com/jackc/pgx) |
| 9 | +- `Database migrations` using [Atlas](https://atlasgo.io/) |
| 10 | + |
| 11 | +## Technology Choices |
| 12 | + |
| 13 | +The author of this repository carries opinions about how to best organize an application / repository. Those opinions / choices are described below: |
| 14 | + |
| 15 | +1. No ORM (Object Relational Mapper) - Golang has a few ORMs that are popular, in particular [GORM](https://gorm.io/) and [Ent](https://entgo.io/). |
| 16 | + 1. ORMs hide SQL, and SQL is already super declaritive and easy to read |
| 17 | + 2. ORMs typically require some schema setup, and code generation, and knowing what goes where |
| 18 | + 3. It can be difficult to optimize ORM SQL |
| 19 | +2. Echo for the REST API - There are a lot of http frameworks in the golang echosystem, including [Echo](https://echo.labstack.com/) and [Gin](https://gin-gonic.com/). Echo seemed to provide a lot out of the box, including things like Auth. |
| 20 | +3. PGX for the database - `database/sql` would be fine as well, but PGX is PostgreSQL optimized and includes connection pooling. |
| 21 | +4. Taskfile instead of Makefile - There is nothing inherently wrong with Makefile, Taskfile is a reasonable alternative with simple, validatable YAML syntax |
| 22 | +5. Pre-commit - makes sure that users cannot commit / push code that isn't up to standards |
2 | 23 |
|
3 | 24 | ## Pre-requisites
|
4 | 25 |
|
5 |
| -1. Install [Pre-Commit](https://pre-commit.com/). This project uses pre-commit to ensure code is all nice and tidy before others can see it. |
6 |
| -2. Install the pre-commit hooks by running `pre-commit install` |
7 |
| -3. Install [Atlas](https://atlasgo.io/getting-started). Atlas is used for database migrations |
| 26 | +1. Install [Docker](https://docs.docker.com/get-docker/). Used for testing |
| 27 | +2. Install [Pre-Commit](https://pre-commit.com/). This project uses pre-commit to ensure code is all nice and tidy before others can see it. |
| 28 | +3. Install the pre-commit hooks by running `pre-commit install` |
| 29 | +4. Install [Atlas](https://atlasgo.io/getting-started). Atlas is used for database migrations. Note: you can skip this step and just rely on docker |
| 30 | + |
| 31 | +## Project Structure |
8 | 32 |
|
9 |
| -## Getting Started |
| 33 | +- `cmd` - this is where the default config and the main app lives |
| 34 | +- `pkg` - this is where most of the code lives |
| 35 | + - `common` |
| 36 | + - `config` - for loading the config file / incorporating environment variable overrides |
| 37 | + - `db` - the underlying database in PGX, and domain specific Repositories |
| 38 | + - `handler` - for handling each of the type of echo requests / routes |
| 39 | + - `models` - core domain model classes, surfaced in the API and used in the Repositories |
| 40 | + - `router` - where we map echo routes to handlers |
| 41 | + |
| 42 | +## Running tasks |
10 | 43 |
|
11 | 44 | This project uses [Taskfile](https://taskfile.dev/) for running tasks. The following tasks are available
|
12 | 45 |
|
13 |
| -* build: Builds a local executable, outputs to out/bin/gomin |
14 |
| -* clean: Cleans up build artifacts, including out, bin, and test reports |
15 |
| -* d.build: Builds the docker iamge, marks it as latest |
16 |
| -* d.down: Shuts down all docker containers in the docker compose file |
17 |
| -* d.up: Starts up all docker containers, builds and runs the API as well |
18 |
| -* db.migrate: Runs the database migration, ensures that the local postgres database is running |
19 |
| -* db.up: Starts the database WITHOUT migrations |
20 |
| -* server.run: Starts the database, runs migrations, builds the server, and starts the server |
21 |
| -* test: Runs all of the tests in all of the go source directories |
| 46 | +- `build`: Builds a local executable, outputs to out/bin/gomin |
| 47 | +- `clean`: Cleans up build artifacts, including out, bin, and test reports |
| 48 | +- `d.build`: Builds the docker iamge, marks it as latest |
| 49 | +- `d.down`: Shuts down all docker containers in the docker compose file |
| 50 | +- `d.up`: Starts up all docker containers, builds and runs the API as well |
| 51 | +- `db.migrate`: Runs the database migration, ensures that the local postgres database is running |
| 52 | +- `db.up`: Starts the database WITHOUT migrations |
| 53 | +- `server.run`: Starts the database, runs migrations, builds the server, and starts the server |
| 54 | +- `test`: Runs all of the tests in all of the go source directories |
| 55 | + |
| 56 | +For some common tasks: |
| 57 | + |
| 58 | +- `task db.migrate` to start the local postgres database and run migrations to get the database current |
| 59 | +- `task server.run` ensures the database is running and builds and starts the rest server - it is available at http://localhost:1323 |
| 60 | +- `task test` you must start the database first using `task db.migrate` and then you can run tests |
| 61 | + |
| 62 | +## Writing Tests |
| 63 | + |
| 64 | +This project primarily uses _E2E_ tests hitting the API directly and using the docker postres database. |
| 65 | + |
| 66 | +Tests live in `pkg/common/router` - create a new `xxx_test.go` file as needed |
22 | 67 |
|
23 | 68 | ## Roadmap
|
24 | 69 |
|
|
0 commit comments