Revolut Backend coding test
Built on Windows PC using intellij & jdk-10
There is a unit test at _test_app, IntegrationTests
This exercises the endpoints, this will run from intellij (for example) and starts its own REST server (ie it does not require the app to be run first)
Run _test_app, app.kt, fun main(), this will start the server and allow manual tusting
Ctrl-C will quit the app
By default, REST server listens on port 8123, this can be configured in the file kovert.conf (deployed with app)
APIs can be tested using curl (or Postmaster)
The API urls are
PUT /api/account/create/:name/:initialBalance
:name - Account name (String)
:initialBalance - Initial balance of account (Int) (represents pennies/cents)
returns: AccountId (Long)
GET /api/accounts/details/:accountId
:accountId - Id of account as returned by create above (Long)
return: Account object (Json)
PUT /api/account/transfer/:from/:to/:amount
:from - ID of account to take money from (Long)
:to - ID of account to send money to (Long)
:amount: Amount in pennies/cents (Int)
returns: Transaction ID
I have tried to find the balance between the absolute simplest implementation that fulfils the spec (ie TDD/Agile) and a solution that represents my ability as a developer of enterprise products.
I would also like to note that Kotlin is not my first language and, as such, my code may not be the most "idiomatic".
- Some commits are retained to demonstrate development process. In an enterprise solution, some commits may have been merged when pushed to master to keep the repository cleaner.
The following items would be coded in an enterprise solution but are omitted from the challenge, either for the sake of clarity or because of time constraints.
- There is no logging
The following improvements were not coded due to lack of familiarity with the REST library used
- HTTPS would be more secure
- Data (such as transfer details) should be POST as json body rather than PUT
- Data model is used in both API and datastore, this creates a coupling which I would normally break by creating a Data Abstraction Layer. This has been omitted for simplicity
- Services do not perform error checks (null names, negative balance, etc). These checks would be done early in the service and return the appropriate errors to the user.
- Datastore is clearly too simplistic for an enterprise solution.
- Transactions, using a suitable DB, transactions would be supported to prevent partial transactions (eg taking funds from source account but failing to add them to the target account)