Create light weight api server using Spark Java [2]

silentsudo

Ashish Agre

Posted on September 7, 2017

Create light weight api server using Spark Java [2]

Hi everyone,

Continuing from previous section https://dev.to/silentsudo/create-light-weight-api-server-using-spark-java

Now that we have our hello world server ready, lets remove hello world and make it a proper api-server.

We will arrange our codebase in following structure:

package
--config (any configuration on server)
--models (usually POJO classess)
--routes (controller for api to manage requests)
--services (business logic to deal with data coming from routes)
--database (for time being we will create in-memory db with java's collection framework)

First we will do some server configuration:
By default Spark server boots on 4567 port, lets change that, using
Spark.port(HTTP_PORT);

we have configuration package now we will use this.
Here is how configuration class looks like:

import spark.Spark;

import java.net.Inet4Address;
import java.net.UnknownHostException;

public final class Config {

    private  final int HTTP_PORT= 9090;

    public Config() {
        Spark.port(HTTP_PORT);
    }

    public int getPort() {
        return this.HTTP_PORT;
    }

    public String getHost() {
        try {
            return Inet4Address.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            return "http://localhost";
        }
    }

}

and below is our main class

import in.silentsudo.blabber.config.Config;
import spark.Spark;


/**
 * Greeting world!
 */
public class Main {
    public static void main(String[] args) {
        System.out.println("Starting server...");
        Config config = new Config();


        Spark.get("/sayhello", (request, response) -> {
            return "Hello buddy!!!";
        });

        System.out.println("Open : " + config.getHost() + ":" + config.getPort());
        System.out.println("Server started successfully.");
    }
}

You should get something like this in console and your server is up and running with these details:

Starting server...
Open : 172.16.1.211:9090
Server started successfully.

We haven't done anything convinsing yet,
Now we create our in-memory database using collection framework.

Designing Backend entities:

Light-weight Entities in our app will be:

  • User(app user with their information)
  • Tweet(created by user having 140 chars may or may not have likes)
  • Like(belongs to only 1 tweet and 1 user, if any such information is absent that like is useless, imagine a like where we dont know who was the person and which was the tweet)
  • Logger(small class to keep track of what all things happening on server)

Designing URL structures and methods:

There are lots of wonderfull rest-api design documents available:

I took specific part from here: https://www.redhat.com/archives/rest-practices/2011-August/pdfa1nfEjPMmT.pdf

API Methods:

Method Scope Semantics
GET Collection Retrieve all resources in a collection
GET resource Retrieve a single resource
HEAD Collection Return all resources in a collection (header only)
POST Collection Create a new resource in a collection
PUT resource Update a resource
DELETE resource Delete a resource

URL Structure:

URL structure also play very crucial role in designing api. We store data that is relevant for our purpose and ignore other irrelevant information, thereafter if multiple clients(mobile, other webserver, html pages using js) wants to access this data we expose them using rest interface, so the way we expose such data should also follow some standard pattern.

We will define url structure in following way:

  • ip/pathtoresource/
  • ip/pathtoresource/if-subresource
  • ip/pathtoresource/if-subresource/if-sub-sub-resource

Considering above pattern lets see how our apis urls should looks like:

  • ip/users/ (all users, usually this is blocked who wants to tell the world i have so many people)
  • ip/users/:id (specific user, mostly used when we want to get our own information, call to user data other than current user should be restricted)
  • ip/users/:id/tweets (get all tweets for specific user)
  • ip/tweets/ (all public tweets)
  • ip/tweets/:id (specific tweet with id)
  • ip/likes/:id (Specific like)
  • ip/users/:id/likes (get all likes from this user)

I will revisit this if something smells fishy with our URLs...

In next article we will see how to write urls using Spark-Java and associate specific resource with it.

Thank you for reading!

💖 💪 🙅 🚩
silentsudo
Ashish Agre

Posted on September 7, 2017

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related