This is an opinionated* reference implementation of a Go microservice. It is not intended to be used as production code but it is written with the (opinionated*) standards of production code.
Whenever possible, idiomatic Go is used with as few dependencies (opinionated*) as possible. Go's idiom of using very short variable names is not followed much. I mostly agree with this idiom but when introducing a new language, I feel verbosity is best.
* If you have a different opinion that you think would make this implementation better, file an issue or send me a pull request.
effective-octo-garbanzo
is a microservice that sits on its own Postgres relational database. The name was autogenerated by GitHub's new repository form. Per the name, the service serves Octos and Garbanzos in a parent/child relationship. Octos have a name
attribute which must be unique (the name is included in the resource URI). Garbanzos have a type
attribute (valid types are DESI
and KABULI
) and a diameter-mm
attribute which must be a positive decimal number.
The database schema is migrated on startup from a self-contained schema. Note that multiple migrations are supported but since this is reference implementation, only one migration will ever be included here.
There are several dependencies that need to be installed prior to running the tests:
goimports
go get golang.org/x/tools/cmd/goimports
ginkgo
go get github.com/onsi/ginkgo/ginkgo
docker-compose
https://docs.docker.com/compose/install/- Docker https://docs.docker.com/engine/installation/
There are several Go dependencies that are vendored as git submodules. Run the following after cloning the repository and after each pull:
git submodule update --init --recursive
Finally to actually run the tests:
./scripts/test
Either by running the tests or by running the following script, a docker image is created:
./scripts/build
HATEOAS
All requests are validated by an Authorization
header. The value must contain a JWT validated by the public key retrieved from the VERIFIER_KEY_URI
endpoint.
This service only returns JSON responses. If there is a response body (the response status is not 204 - No Content
), the Content-Type
response header is application/json
.
Field | Description |
---|---|
code |
The HTTP status code of the response. |
error |
The summary error message of the response. |
errors |
The list of specific errors (optional, only present when there are multiple errors). |
status |
The descriptive status code. |
{
"code": 400,
"error": "Error creating new octo",
"errors": [
"name must be present",
"name must match regular expression '^[\\w-]+$'"
],
"status": "Bad Request"
}
200 - OK
: Only 200 - OK
is returned.
Field | Description |
---|---|
health |
Link to the health endpoint. |
octos |
Link to the octos collection endpoint. |
{
"health": "http://localhost:8080/health",
"octos": "http://localhost:8080/octos"
}
200 - OK
: Currently only 200 - OK
is returned.
Field | Description |
---|---|
health |
The health of the service. Currently only GOOD is supported. |
{
"health": "GOOD"
}
200 - OK
: Returned on success.
500 - Internal Server Error
: Returned when there is an internal server error. The standard error body is returned.
Returns a list of octos. See GET /octos/:octoName
for the definition of an octo.
[
{
"link": "http://localhost:8080/octos/kraken",
"name": "kraken",
"garbanzos": "http://localhost:8080/octos/kraken/garbanzos"
}
]
Field | Description |
---|---|
name |
The name of the new octo to be created. |
{
"name": "kraken"
}
201 - Created
: The octo was successfully created.
400 - Bad Request
: The request was malformed and could not be processed. The standard error body is returned.
500 - Internal Server Error
: Returned when there is an internal server error. The standard error body is returned.
Returns the newly created octo. See GET /octos/:octoName
for the definition of an octo.
{
"link": "http://localhost:8080/octos/kraken",
"name": "kraken",
"garbanzos": "http://localhost:8080/octos/kraken/garbanzos"
}
Field | Description |
---|---|
octoName |
The name of the octo to be retrieved. |
200 - OK
: Returned on success.
400 - Bad Request
: The request was malformed and could not be processed. The standard error body is returned.
404 - Not Found
: The requested octo could not be found. The standard error body is returned.
500 - Internal Server Error
: Returned when there is an internal server error. The standard error body is returned.
Field | Description |
---|---|
link |
This resource. |
name |
The name of the octo. |
garbanzos |
Link to the garbanzos collection endpoint for this octo. |
{
"link": "http://localhost:8080/octos/kraken",
"name": "kraken",
"garbanzos": "http://localhost:8080/octos/kraken/garbanzos"
}
Field | Description |
---|---|
octoName |
The name of the octo to be deleted. |
204 - No Content
: Returned on success.
400 - Bad Request
: The request was malformed and could not be processed. The standard error body is returned.
404 - Not Found
: The requested octo could not be found. The standard error body is returned.
500 - Internal Server Error
: Returned when there is an internal server error. The standard error body is returned.
Field | Description |
---|---|
octoName |
The name of the octo for which garbanzos are to be retrieved. |
200 - OK
: Returned on success.
400 - Bad Request
: The request was malformed and could not be processed. The standard error body is returned.
500 - Internal Server Error
: Returned when there is an internal server error. The standard error body is returned.
Returns a list of garbanzos. See GET /octos/:octoName/garbanzos/:apiUUID
for the definition of an garbanzo.
[
{
"link": "http://localhost:8080/octos/kraken/garbanzos/ac2f1146-c26b-45a7-b72d-3dcaa94c1913",
"type": "DESI",
"diameter-mm": 4.5
}
]
Field | Description |
---|---|
octoName |
The name of the octo in which a new garbanzo will be created. |
Field | Description |
---|---|
type |
The type of the new garbanzo to be created (either DESI or KABULI ). |
diameter-mm |
The diameter of the new garbanzo in millimeters. |
{
"type": "DESI",
"diameter-mm": 4.5
}
201 - Created
: The garbanzo was successfully created.
400 - Bad Request
: The request was malformed and could not be processed. The standard error body is returned.
409 - Conflict
: The parent octo could not be found. The standard error body is returned.
500 - Internal Server Error
: Returned when there is an internal server error. The standard error body is returned.
Returns the newly created garbanzo. See GET /octos/:octoName/garbanzos/:apiUUID
for the definition of an garbanzo.
{
"link": "http://localhost:8080/octos/kraken/garbanzos/ac2f1146-c26b-45a7-b72d-3dcaa94c1913",
"type": "DESI",
"diameter-mm": 4.5
}
Field | Description |
---|---|
octoName |
The name of the octo for which a garbanzo will be retrieved. |
apiUUID |
The API UUID of the garbanzo to be retrieved. |
200 - OK
: Returned on success.
400 - Bad Request
: The request was malformed and could not be processed. The standard error body is returned.
404 - Not Found
: The requested garbanzo could not be found. The standard error body is returned.
500 - Internal Server Error
: Returned when there is an internal server error. The standard error body is returned.
Field | Description |
---|---|
link |
This resource. |
type |
The type of the garbanzo (either DESI or KABULI ). |
diameter-mm |
The diameter of the garbanzo in millimeters. |
{
"link": "http://localhost:8080/octos/kraken/garbanzos/ac2f1146-c26b-45a7-b72d-3dcaa94c1913",
"type": "DESI",
"diameter-mm": 4.5
}
Field | Description |
---|---|
octoName |
The name of the octo for which a garbanzo will be deleted. |
apiUUID |
The API UUID of the garbanzo to be deleted. |
204 - No Content
: Returned on success.
400 - Bad Request
: The request was malformed and could not be processed. The standard error body is returned.
404 - Not Found
: The requested garbanzo could not be found. The standard error body is returned.
500 - Internal Server Error
: Returned when there is an internal server error. The standard error body is returned.