- I've started the task discovery from API doc
- What's out of scope by the task def:
- We don't need to provide an authorisation to access Fake API
- We cannot use swagger autogen tool
- We need to use low-level HTTP communication (net/http)
- We need to introduce
Create
,Fetch
,List
andDelete
operations for accounts - We need to keep things aligned, so we will introduce the sameish naming convention for client library methods
- The API provides one extra endpoint
Patch
, we don't need to introduce it - I've started provided docker env
- I manually checked if all required endpoints are here and can be used
Delete
does not behave as expected, it basically returns always 200 even for non-existent versionPatch
endpoint does not exist
- I've updated the docker tag to latest and checked again - nothing changed for previous bullet point
- I personally prefer start from data model
- There I found documentation
- There are some small inconsistencies on required fields
- I've added
/cmd/form3/models
folder for all models - File
models/account.go
contains a detailed defintion foraccount
, reversed engineered from YAML. It will be useful forCreate
(marshall/unmarshall) andFetch
(unmarshall) operations- The
account
definition in YAML is quite big and we need to limit the complexity - I took only relevant for the first version set of fields
- The
- File
models/accounts.go
contains an account collection definition forList
operation, actually it is only an array ofmodels/account.go
entities - For
List
endpoint we need to introduce only pagination, so we addedmodels/pagination.go
for pager definition - it contains two fields -Number
(default 0),Size
(default 100) - I played with Postman, and discover HATEOAS media links, so I've added
models/links.go
- From perspective of production readiness I can mention:
- It should have all meaningful unit tests
- It should have all meaningful e2e tests
- It should be easily extensible
- We need to keep SRP principle applied - so we try to keep logic separated
- New features for entity management should be simple and straighforward
- It should log all important steps
- The idea of pluggable API can be introduced via interfaces
- So we added
cmd/form3/form3.go
which contains the API aggregator
- So we added
type Form3 struct {
Account Account.ClientInterface
}
func New(host string, timeout time.Duration) *Form3 {
return &Form3{
Account: Account.NewClient(host, timeout),
}
}
And the aggregator will be called in the unified way
f3 := Form3.New(os.Getenv('FORM3_API'), time.Duration(5 * time.Second))
f3.Account.Create(...)
We can extend this aggregator in the future
type Form3 struct {
Account Account.ClientInterface
Claim Claim.ClientInterface
Mandate Mandate.ClientInterface
}
func New(host string, timeout time.Duration) *Form3 {
return &Form3{
Account: Account.NewClient(host, timeout),
Claim: Claim.NewClient(host, timeout),
Mandate: Mandate.NewClient(host, timeout),
}
}
f3.Mandate.Create(...)
f3.Claim.List(...)
- We need to follow 12-factor app principles
- We introduced automatic tests for docker image, check
CMD
- We inject
FORM3_API
via env
- We introduced automatic tests for docker image, check
- We keep models simple, without any logic
- Implement complex validation rules for all
countries (currently done only for GB, take a look in the
validation
folder and docs) - Implement IBAN generation
- Implement PATCH operation
- OrganisationID must be injected into Form3
- Models shared between different domains
- Add CI/CD
- Golang 1.14
- UUID from Google
- validation.v9 library with tag-based validation
- testify/assert & testify/mock
- Install docker and docker-compose
- Run
docker-compose up
- Press Ctrl-C after test review
\_ cmd/form3
\_ account # account client interface implementation
\_ common # common helpers
\_ models # shared models
\_ test # test helpers
\_ validation # validators
form3 # API aggregator
\_ scripts
\_ db # db init scripts
\_ test # JSON fixture folder
Makefile # useful shortcuts