Skip to content

Latest commit

 

History

History
107 lines (78 loc) · 7.49 KB

README.md

File metadata and controls

107 lines (78 loc) · 7.49 KB

Crypto Coin Alerts Server API

Build Status Codacy Badge Codacy Badge

Description

The alerts server API is built relaying on the following principal technologies:

At the moment it is supporting the following currency exchanges, more exchanges might be added in the future:

The following alerts are supported while more alert types should be added soon:

  • Fixed price - Receive a notification when a currency gets above or below the given price, you can set a base price to receive a more detailed message.
  • Daily price - Receive a daily notification with the price of the currencies of your choice (currently disabled).
  • New currencies - Receive a notification when a currency is addded to the exchanges of your choice.

Compile

Execute sbt compile command for compiling the application.

Run

In order to run the application locally, you will need the following dependencies:

  • A PostgreSQL instance (strictly necessary).
  • A Mailgun API key (necessary for sending emails).

There are some environment specific configuration values that you need to set to run the application successfully, the recommended way is to create a file .env (which is ignored by git to avoid you pushing sensitive data by accident)), then take the following content and update it according to your needs:

# database
export CRYPTO_COIN_ALERTS_PSQL_HOST="localhost:5432"
export CRYPTO_COIN_ALERTS_PSQL_DATABASE="crypto_coin_alerts"
export CRYPTO_COIN_ALERTS_PSQL_USERNAME="postgres"
export CRYPTO_COIN_ALERTS_PSQL_PASSWORD="password"
# from mailgun
export MAILGUN_API_SECRET_KEY="REPLACE_ME"
export MAILGUN_DOMAIN="www.cryptocoinalerts.net"

Last, as the development environment is prepared for running without nginx, uncomment the line with this text play.filters.enabled += "play.filters.cors.CORSFilter" (or just add the text as a new line) from application.conf.

Execute source .env; sbt run command for running the application.

A more flexible way would be to modify application.conf file to your needs and then execute sbt run command.

Testing

In order to run the tests execute sbt test command, note that Database tests depend on docker to run.

Most of the tests belong to one of these categories:

  • Simple tests.
  • Database tests
  • API tests.

Simple tests

A simple test is like a relaxed unit test, it tests a single method without mocking external libraries, for example, see JWTServiceSpec.

Database tests

A database test is basically an integration test that ensures that a data handler is working as expected, it uses a real PostgreSQL instance provided by Docker with the help of docker-it-scala library.

The postgres image is created before running the test, we apply all the play evolutions to have the schema updated, and the image is destroyed after running the test.

All of these tests are extending PostgresDataHandlerSpec, for example, see UserPostgresDataHandlerSpec.

API tests

An API test is similar to an integration test because it is testing the whole system integration swapping external dependencies for internal ones:

These tests are useful for verifying that the API works as expected on the client side, they intention is to cover the use cases that are going to be used on the clients consuming the API.

Development

Here are some details about the architecure design, they could be useful if you want to understand the code.

Playsonify

We use the playsonify extensively, you are encouraged to read its documentation.

When working with non-blocking results, the code could get an awful level of nesting while computing a result using several steps, we use a simple monad transformed called FutureOr), you could see its usage at UserService#create().

Configuration

There are several components that are configurable, as we already are using play framework, it is very simple to integrate the typesafe-config which loads the configuration from the application.conf file (hopefully we will switch to more typesafe configuration library in the future).

We are creating a base trait that could be easily extended for testing, and implementing the config depending on the Configuration from play framework, note that no sensitive information should be stored in the configuration files that are being tracked by git, a better approach is to declare them as environment variables or Java system variables.

See JWTConfig.

Controllers

For building the HTTP API, we use the controllers package, the controller classes make extensive use of the AbstractJsonController (from playsonify), it help us to build a controllers that receives JSON and produces JSON (it handles application errors as well).

The controllers could receive a model (that should be deserializable using play-json) and produce model (that is serializable using play-json).

A controller responsibility is very simple:

  • Deserialize the input (if any).
  • Delegate the action to the proper service.
  • Serialize the result using a response HTTP Status that makes sense for the action.

See UsersController.

Services

The services package is the one containing most application logic and rules, the controllers depend specifically on this package for performing most actions and retrieving data.