Our fictive application — Backend setup

Rasmus Eriksson
4 min readJun 27, 2019

Read https://medium.com/p/e17b2df29bf2 to get some context.

The grunt work

We decided on Spring Boot. Lets use https://start.spring.io/ to generate our project. The backend project can be found https://github.com/MrMjauh/backend.timetracker under the branch backend_setup. There is not much to say about the tooling here, we choose Gradle over Maven and use JUnit.

We have a few technical choices here. We decided on MongoDB and there are tons off different tools that do the same job. We could go for a “low abstraction but a lot of boilerplate” option with https://mongodb.github.io/mongo-java-driver/. Since we are going to use a lot of the spring ecosystem it would be a shame not to use https://spring.io/projects/spring-data-mongodb. This will gives us a “springy” syntax handling repositories and somewhat JPA(ish) familiarity.

At some point we are going to need Oauth2 flow for handling authentication. So we add the oauth2-client. Actuators will be used later for monitoring and health checks, so we add them also. I am not the biggest fan of Lombok, but lazy me wants access to builders and not write boilerplate code. We also add Jacoco and Checkstyle.

Checkstyle is going to be used for linting the code, making sure it is consistent. A codebase can easily become filled with different types of coding styles and seem disorganized even though the core might be good. The main goal with Checkstyle is to create consistency. The spring checkstyle works https://github.com/spring-io/spring-javaformat, but we need to remove some of the things we do not like. From the root directory we create a config/checkstyle project with a checkstyle configuration. Copy over the content from https://github.com/spring-io/spring-javaformat/blob/master/src/checkstyle/checkstyle.xml. Checkout config/checkstyle/checkstyle.xml for the final result.

Spring dev tools is nice tool for fast prototyping. It will automatically check for changes in the classpath and restart the server. This means a rebuild will trigger a reload.

The build.gradle file should look something like this:

We replace the built in application.properties file with an application.yml file (we are going to heavily modify this later).

We need to test our wiring before we push any code, we are all familiar with docker so lets startup a docker container with MongoDB for testing purposes. On Linux it can be done with:

docker run -d -p 27017:27017 -v ~/data:/data/db mongo
Our sample yaml file

Export environment variables:

  • MONGO_HOST = localhost
  • MONGO_PORT = 27017
  • MONGO_DATABASE = timetrackr

In the root of the project write gradle bootRun. Hopefully the connections to the db goes smoothly and visiting http://localhost:8080/hello prints a familiar message.

Common configuration

We add a couple of configuration options and a resource file to make it a bit more typed and specific. This is just some common configuration that I like to have. ErrorCode will later be used for sending specific error code outs to the client. Adding javadoc for the ErrorCode class 👍. So when you get asked question about error codes and what they mean just javadoc them!

Hint! gradle javadoc will produce something like this:

Javadoc for error codes

We go with the philosophy of denying then keep it open and set as standard for all exposed endpoints to be denied in the configuration. This can of course change over the course of the project. We also set default content type and just in case set it to return UTF-8 as default (In https://tools.ietf.org/html/rfc5987, iso-8859–1 is the standard reply charset if no other is provided). For dev, we really don’t care that much.

Lets add some support for exceptions and some logging for it. This is a great way to deny a common attack vector, where stacktraces leak out to production. Also it creates a more unified way for the consumer of our API and what they can expect to get. Visit localhost:8080/runtime and you’ll see an example of how errors are handled.

We add Swagger for dev and stage purposes, so people can easily check the APIs and what they return. This will be modified during later articles with authentication and authorization. See https://github.com/MrMjauh/backend.timetracker for the full configuration.

Screenshot of swagger documentation

We have a base plate to work with now. We have general error handling, logging, strict rules, linting, database connection and more. Now we can finally start doing some real work!

Clone the repository https://github.com/MrMjauh/backend.timetracker in branch backend_setup and start it with gradle bootRun. You can now visit localhost:8080/hello and localhost:8080/runtime to checkout the API samples. As all the configuration is not present in the article, you really should check it out.

In the next part we will start diving into the authentication and authorization of the application. You can read about it here https://medium.com/@raser891/our-fictive-application-backend-authorization-and-tokens-d309b2eb5ac4.

--

--