We follow the Effective Go guide as well as the Go Code Review Comments and Go test comments.
We strive to create packages that contain a single domain, and not packages based on what they are (e.g. repository
, service
, controller
).
The main domains and packages are designed for use by the GraphQL API. Anything used by the gRPC API will be separated into a different package.
E.g. a package for a Team
domain should contain all the necessary code to work with Team
entities.
Use singular names for packages, e.g. team
, user
, application
.
- Create a new directory with the domain name in the
internal
directory.- We have some folders to group similar domains, like
internal/persistence
. Use them if it makes sense.
- We have some folders to group similar domains, like
- If the domain requires a database, update .configs/sqlc.yaml to include the new domain.
E.g:
sql: # ... - <<: *default_domain name: "{{PACKAGE_NAME}} SQL" queries: "../internal/{{PACKAGE_NAME}}/queries" gen: go: <<: *default_go package: "{{PACKAGE_NAME}}" out: "../internal/{{PACKAGE_NAME}}/{{PACKAGE_NAME}}sql"
- When you've created your model(s) in the new package, add a line to .configs/gqlgen.yaml to automatically bind the model to the GraphQL schema.
E.g:
autobind: # ... - "../internal/{{PACKAGE_NAME}}"
- After you've created your dataloader, add it to internal/cmd/api/http.go.
We use sqlc to generate Go code from SQL queries.
Each domain should have a queries
directory with the SQL queries for that domain.
See step 2 in the previous section for how to configure sqlc.
When a .sql
file is changed, run make generate-sql
to generate the necessary code.
We usegithub.com/vikstrous/dataloadgen
to create dataloaders.
Dataloaders are used to batch and cache requests to the database, and are scoped to the request.
Whenever you request a single resource, and there's a way to request multiple resources at once, use a dataloader.
For an example, check the internal/team/dataloader.go file.
We have defined a set of practices for the Graph-API in the graphql_practices.md file.
Whenever a .graphqls
file is changed, run make generate-graphql
to generate the necessary code and documentation.
All destructive actions as well as actions that changes permissions should be logged.
See the audit logging practices for more information.
All code changes must be submitted as pull requests. The main branch is protected.
Code review is suggested for all pull requests, but required for those described below. If at least one participant of the pull request is familiar with the codebase, the review can be skipped.
All checks should pass before merging.
- Changes that affects the public API (e.g. changes to any
.graphqls
file) - Changes that introduces or changes practices already described in this document
For Go code, we use gofumpt, and for all other code we provide a configuration file for Prettier. Code formatting is enforced by the GitHub workflow, and pull requests with incorrect formatting will fail the build. It is recommended to configure your editor to format code on save.