RESTful API for money transfers between accounts.
- Java 11
Alternatively project can be build and run with Docker.
Service is using maven wrapper, so no need setup maven execution environment.
- Database is running completely in memory. After the application is stopped, all the data will be lost.
- Data consistency is guaranteed by append-only approach for storing the data and usage of idempotency keys.
- Pessimistic locking used for update accounts balance.
Scripts to populate database schema and at startup apply changes.
To run unit and integration tests execute the following command:
./mvnw clean verifyBuild an executable jar:
./mvnw clean packageThen run it:
java -jar ./target/transfer-jar-with-dependencies.jarBy default server is running on port 4000. It can be changed using server.port system property, e.g.:
java -Dserver.port=4000 -jar ./target/transfer-jar-with-dependencies.jarFirst run may take some time. Provided image is not optimized for any kind of workload and can only be used for testing.
First build an image:
docker build -t transfer:latest .Start the container using the following command:
docker run --rm -it -p 4000:4000 transfer:latestAll rest apis exist in http-client
Request: POST /api/v1/accounts
Request body:
{"currency":"USD"}
The output of the command should be similar to the following:
HTTP/1.1 201 Created
Date: Tue, 28 Jan 2020 16:00:52 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Server: Jetty(9.4.18.v20190429)
{
"accountNumber": "d00035af-46e6-4ba4-bf90-f6718bd49ab2",
"currency": "USD"
}accountNumber in the response is an ID of a newly created account.
Request: GET /api/v1/accounts/:account_number
Request body: No
The output of the command should be similar to the following:
{
"accountStatusType": "ACTIVE",
"accountNumber": "d00035af-46e6-4ba4-bf90-f6718bd49ab2",
"createDatetime": [2020,1,28,19,30,52,662261000],
"balance": 0.00,
"currency": "USD"
}Newly created accounts always have a 0 balance.
Request: POST /api/v1/accounts/deposit
Request body: JSON document with the following properties
transactionId- id of the deposit transaction. It is used for idempotency. If not set in request created by server.accountNumber- account number for top-upamount- amount to credit in currency of account .
The output of the command should be similar to the following:
HTTP/1.1 201 Created
Date: Tue, 28 Jan 2020 16:24:25 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Server: Jetty(9.4.18.v20190429)
{
"transactionId": "5f273e85-74fc-4eab-b5cf-1e2991c505bc"
}Request: POST /api/v1/accounts/withdraw
Request body: JSON document with the following properties
transactionId- id of the deposit transaction. It is used for idempotency. If not set in request created by server.accountNumber- account number for top-upamount- amount to credit in currency of account .
The output of the command should be similar to the following:
HTTP/1.1 201 Created
Date: Tue, 28 Jan 2020 17:12:01 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Server: Jetty(9.4.18.v20190429)
{
"transactionId": "2"
}Request: POST /api/v1/transfers
Request body: JSON document with the following properties
transactionId- id of the transfer. It is used for idempotency. It should be a new random UUID every time.source_account_id- id of the source account. It will be debited.target_account_id- id of the target account. It will be credited.amount- amount to transfer in cents.
The output of the command should be similar to the following:
HTTP/1.1 201 Created
Date: Tue, 28 Jan 2020 17:31:26 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Server: Jetty(9.4.18.v20190429)
{
"transactionId": "3"
}
After a successful transfer, new balances can be observed by querying the account transaction list.
Request: GET /api/v1//accounts/:account_number/transaction
The output of the command should be similar to the following:
HTTP/1.1 201 Created
Date: Tue, 28 Jan 2020 17:57:47 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Server: Jetty(9.4.18.v20190429)
{
"accountTransactionDTOList": [
{
"createDatetime": [2020,1,28,20,50,1,365024000],
"financialAccount": 2,
"amount": 10.00,
"balance": 10.00,
"transactionType": "DEPOSIT",
"transfer": 1,
"transactionId": "3"
}
]
}