template-go-api

command module
v0.0.0-...-a39b735 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 4, 2024 License: MIT Imports: 1 Imported by: 0

README

Development

This project is a template for implementing an API in a robust and reliable way. It uses the echo web framework to serve the API and the oapi-codegen tool to generate the API server from an OpenAPI document. The build system uses bingo to manage build dependencies.

This project is self-contained in that it provides static web assets - so you can run it and connect to http://127.1:10721/ to play around with the API.

Project organisation

All generated code ends in .gen.go and is not committed.

  • api/ and internal/api - The OpenAPI document and the oapi-codegen configs respectively. The generated code is split into the code for endpoints (endpoints.gen.go) and the data types (models.gen.go).

  • mock/ and .mockery.yaml - The mockery generated code and its configs respectively.

  • internal/storage - Implements a storage layer. When using this template, you'd need to replace internal/storage/storage.go with your own storage routines.

  • internal/server - Implements the server. The main thing to replace here is internal/server/api.go with your own API implementation. See the "Implementing the API" section below.

  • internal/static - A simple web UI for testing the API server. Remove the references to it in internal/server/server.go to disable it.

Makefile targets:

  • all - default target. It will run generate, test, lint and build.

  • generate - runs any code generators. Preferably using go generate. Generated go files should end in *.gen.go and .gitignore is set to ignore them.

  • lint - runs linters.

  • test - runs tests.

  • build - runs the build.

  • cobra-cli - this can be used to run cobra-cli. The CMD arg can be used to create new commands. Say you need db migration. You can make a migrate command like so:

    make cobra-cli CMD=migrate
    

Makefile targets for CI systems:

  • ci-all - this will run ci-generate, ci-test, ci-lint and ci-build.

    Artifacts: *.gen.go, reports/, bin/

  • ci-generate - same as generate.

    Artifacts: *.gen.go

  • ci-lint - same as lint.

    Artifacts: reports/

  • ci-test - same as test.

    Artifacts: reports/

  • ci-build - same as buils.

    Artifacts: bin/

Consistency

The project has a .editorconfig file to get consistency in edits. A full build can be run with make and it will run go generate with the correct env vars set, run tests and then do a build. Test results will be thrown up in a browser tab. The tests include a run of golangci-lint as well as yamllint on the OpenAPI document. Ideally folks using this template would enable golangci-lint in their IDE/editor.

There's also a goal to limit the amount of code that needs to be written. At the time of this writing around 25% of the code is written, 10% is written test code and the rest is generated code.

CI Ready

All make targets have a ci- variant. These produce artifacts for code quality and test results and test coverage in the reports/ directory.

Instrumentation

Using echo middleware, there are Prometheus metrics on endpoints. There's also timing for storage calls. The latter would need to be changed for an actual project, but the general idea is there.

Implementing the API

Delete the petstore implementation in internal/server/api.go leaving just the API type and the NewAPI function. Modify them with the state they need. Then start running make to learn what functions you need to implement.

$ make
go fmt ./...
go vet ./...
# gitlab.com/lyda/template-go-api/internal/server
internal/server/server.go:25:37: cannot use NewAPI(db) (value of type *API) as api.StrictServerInterface value in argument to api.NewStrictHandler: *API does not implement api.StrictServerInterface (missing method DeletePet)
make: *** [Makefile:32: test] Error 1

When implementing these, look in internal/api/endpoints.gen.go for the types the functions need to accept and return. Look in internal/api/models.gen.go for the types of the objects you're storing/sending.

TODO

  • Use the embedded OpenAPI document to verify requests and responses as middleware.
  • Generate the javascript library for this api.
  • Make a fully json schema drive UI - maybe something other than alpaca?
  • Implement tracing with OpenTelemetry.
  • Have the UI exercise all API endpoints.
  • Generate a fuzz tester to run against the server. Have a make target to run the server and then run the fuzz tester against it.
  • Implement CI configs for Gitlab and Github.

A special mention for a thing not to do:

  • The least interesting thing to use an OpenAPI document for: generate documentation.

Deployment

There are Makefile targets for generating a docker container and for deploying to a local kind cluster. It can also create a kind cluster with contour for ingress.

Makefile targets for deployment:

  • container - builds a container with docker.
  • create-kind-cluster - creates a kind cluster if one does not exist.
  • deploy-kind - deploys image to kind and deploys the application to the kind cluster.
  • delete-kind-cluster - deletes the kind cluster.

Makefile targets for CI systems:

  • ci-container - uses kaniko to build a container. It might be of interest to explore alternatives to kaniko: Buildah, podman, buildkit and possibly others. For now kaniko works.
  • deployment - no target for this because this will depend a huge amount on your deployment system. Tools like ArgoCD, Gitlab or others can manage deployment external to the code base.

Documentation

Overview

Package main is the main program.

Directories

Path Synopsis
Package cmd containe the cli commands.
Package cmd containe the cli commands.
internal
api
Package api implements the api (see api/api.yaml).
Package api implements the api (see api/api.yaml).
server
Package server implements the API server.
Package server implements the API server.
static
Package static provides an in memory filesystem.
Package static provides an in memory filesystem.
storage
Package storage stores application data.
Package storage stores application data.
Package mock generates mockery mocks.
Package mock generates mockery mocks.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL