Event sourced Account implementation in go.
Replicates the functionality of the java version. Those are my first steps at learning go language so the code will not shine.
- open account:
POST /api/account/{accountId}?owner={ownerId}
should respond with201
and aLocation
header pointing to the created resource if successful - get account's current state:
GET /api/account/{accountId}
should respond with200
and a json body if account is found, otherwise404
- deposit:
PUT /api/account/{accountId}?deposit={amount}&transactionId={uuid}
should respond with204
if successful - withdraw:
PUT /api/account/{accountId}?withdraw={amount}&transactionId={uuid}
should respond with204
if successful - transfer:
PUT /api/account/{accountId}?transfer={targetAccountId}&amount={amount}&transactionId={uuid}
should respond with204
if successful - close account:
DELETE /api/account/{accountId}
should respond with204
if successful
Tests without any tag are the fast unit tests and are the ones that run during the build phase. Normally, I would hook the remaining tests to the build, however since integration and end to end tests depend on docker daemon, I wanted to avoid broken builds on machines that might not have it set up.
Next level are the integration tests that use both Postgres and Mysql backed event store implementations. Tagged with integration
.
Finally, a couple of end to end tests that focus mainly on sanity testing consistency in a distributed
environment. Tagged with e2e
.
make
The build will only run the fast unit tests.
In order to run the functional integration tests targeting containerized Mysql, run
make integration-test
Those will be much slower - they spawn the actual Postgres and Mysql instances using testcontainers-go and thus require a running docker daemon on the host.
And another round of slow tests that test for consistency in a distributed environment:
make e2e-test
Those will spawn a docker-composed environment with two service instances connected to a Postgres container and a load balancer on top. Tests will be executed against the load balancer, simulating a distributed environment and asserting that the service can scale and remain consistent.
In order to run the build with all test levels: unit, integration and end to end, run
make full
Service can be started with an in memory event store implementation using
make run
Service will start on localhost:8080
The same, but packaged in a docker container:
make docker-run
Alternatively, two instances packaged in a docker container, connected to a Postgres container and exposed via Envoy Proxy load balancer using:
make compose-run
This time the service will also be accessible on localhost:8080, just that this time requests will go via a load balancer to two service instances in a round robin fashion and with a shared Postgres database.
Basic metrics are exposed to Prometheus and sample configuration of Prometheus together with Grafana and a service/envoy dashboards can be accessed by spawning a composed environment using
make compose-run
Prometheus is exposed on port 9090 and Grafana is available on port 3000.