Supervision is taking over payment management from SSCL. Rather than adding to the Sirius PHP monolith, this was an ideal opportunity to break out into a new service Two new microservices:
finance-hub
- the “front end” applicationfinance-api
- the “back end” application
Similar approach to the other Golang “microfrontends”, with the following packages:
- Contains the HTTP handlers for the API requests, which respond with HTML
- Differs from existing implementations in two ways:
- Handlers are structs rather than functions (effectively giving each its own namespace)
- Handlers conditionally return HTML “partials” instead of full pages
- Handlers are structs rather than functions (effectively giving each its own namespace)
- The latter allows us to swap out DOM elements without a full page render using htmx, with the logic abstracted out to a common execute function
- Very similar to existing implementations, with two differences:
- As our data is fetched from two sources -
opg-sirius
andfinance-api
- the client exposes two request functions - A simple cache of user data
- As our data is fetched from two sources -
- Contains the .gotmpl HTML templates
- Navigation is done using htmx, which specifies where to fetch the partial and what element to replace (
tabs.gotmpl
being a good example) - htmx also allows swaps outside the target element, known as “out of band (oob)”, and this is used in our error summary rendering
All requests and responses between the two services are JSON in the form of Go structs, within the shared package. This ensures both services adhere to the same contract. There are downsides to this approach, as it couples the services. However, as they are not deployed independently and the API is not versioned, they would essentially be coupled anyway.
This is the “back end” for Finance logic, with a caveat that the initial iteration won’t replace the majority of invoice
generation, which occurs in opg-sirius. The eventual aim is that this will be the only service with write access to the
supervision-finance
database schema.
It consists of the following packages:
- Located in
cmd/api
as this is an entrypoint into the application - Contains the HTTP handlers for the API requests, which respond with JSON
- Handles validation, using
go-validate
and annotations on the data transfer structs, as defined inshared
- Additional validation logic and custom annotations are contained in the
validation
package
- Additional validation logic and custom annotations are contained in the
- Business logic for the application, returning data or errors to
api
in order to be transformed into a response - Service is initialised with an
sqlc
store for data access
- Generated by
sqlc
- a typesafe SQL function generator - SQL queries are written in the
/queries
directory and annotated with a name and arity *.sql.go
files are then generated (usingmake sqlc-gen
), which contain a function for running the query, along with typed structs for their input and output
- Test package that enables
testcontainers
to stand up ephemeral database instances for integration tests
Finance Hub fetches data from two sources:
- User and client data from the Sirius database via the
opg-sirius
API - Finance data from the
supervision-finance
schema in the Sirius database viafinance-api
For local development and testing, we mock these with the following:
json-server
to mock theopg-sirius
API- A Postgres instance in Docker for the
superision-finance
schema
The schema and database migrations are described in the /migrations
package. We use goose
to manage our migrations.
These files are also used by sqlc
when generating its files, as it validates query correctness against the schema when
doing so.