Design and implement a RESTful API (including data model and the backing implementation) for money transfers between accounts.
- keep it simple and to the point (e.g. no need to implement any authentication, assume the APi is invoked by another internal system/service)
- use whatever frameworks/libraries you like (except Spring, sorry!) but don't forget about the requirement #1
- the datastore should run in-memory for the sake of this test
- the final result should be executable as a standalone program (should not require a pre-installed container/server)
- demonstrate with tests that the API works as expected
- Go to list of releases and download the latest build
- Run the api with single java command like
java -jar accounts-api-assembly-0.2.jar
Requires up to date Scala and SBT on the machine
Run tests with
% sbt test
# at the moment the build e2e verification is not run locally - only in ci
Build fat jar with
% sbt assembly
# resulting jar will be at the path like ./target/scala-2.12/accounts-api-assembly-0.2.jar
Run api in dev mode with
% sbt run
StreamApp -> Blaze Server -> Http4s Service -> accounts Service -> Http4s Service -> Blaze Server.
Where only accounts Service are talking to Storage and working with Account aggregates.
It is a streaming app, where results are evaludated only at the edge of the system.
Storage assumed to be an event store, storing transactions only.
% curl http://localhost:8080/transfer --data '{"source":{"id":"d19a413b-def9-44a3-b9eb-e357a3225795"},"destination":{"id":"bd7857ac-8730-4165-b89c-cb37b1f3faa4"},"funds":{"amount":10}}' --verbose
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> POST /transfer HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 138
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 138 out of 138 bytes
< HTTP/1.1 200 OK
< Date: Tue, 20 Mar 2018 00:30:49 GMT
< Content-Length: 0
<
% curl http://localhost:8080/create -XPOST --verbose
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> POST /create HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Tue, 20 Mar 2018 00:28:27 GMT
< Content-Length: 80
<
* Connection #0 to host localhost left intact
{"account":{"id":"d19a413b-def9-44a3-b9eb-e357a3225795"},"balance":{"amount":0}}%
% curl http://localhost:8080/deposit --data '{"account": {"id": "d19a413b-def9-44a3-b9eb-e357a3225795"}, "funds": {"amount": 30}}' --verbose
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> POST /deposit HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 84
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 84 out of 84 bytes
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Tue, 20 Mar 2018 00:29:48 GMT
< Content-Length: 81
<
* Connection #0 to host localhost left intact
{"account":{"id":"d19a413b-def9-44a3-b9eb-e357a3225795"},"balance":{"amount":30}}%
% curl http://localhost:8080/healthcheck --verbose
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /healthcheck HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Tue, 20 Mar 2018 00:34:42 GMT
< Content-Length: 0
<
- It does not allow to configure the server host or port
- It does have production mode with a persistent database
- There is limited validation (for example, it's still possible to deposit negative amount)
- The transfer transaction is currently split into two (limitation of previous version, which did not have transaction ids, but could be fixed in current one)
- The storage does not check for concurrency issues and happily store the order with inconsisten transactions