Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sparkjava: Do routes have to be in main method?

I am new to sparkjava and like it overall. However, do new routes/endpoints have to be defined in the main method? For any significant web application, this will result in a very long main method or I need to have multiple main methods (and therefore split server resources among multiple instances).

These two sparkjava documentation pages seem to define routes in the main method: http://sparkjava.com/documentation.html#routes and here http://sparkjava.com/documentation.html#getting-started.

Is there another way to do this that I'm not seeing? Cursory google searching hasn't shown me a better way ...

=========

Here is the full solution I did based on the answer from Andrew. In my opinion, adding endpoints outside of the main method should be part of the sparkjava documentation page:

Main Method:

public static void main(String[] args) {
    //Do I need to do something more with the Resource instance so that sparkjava notices it and/or reads the routes?
    Resource resource= new Resource(new Service());
}

My resource:

import static spark.Spark.*;
class Resource{

    private Service service;

    Resource(Service service){
        this.service = service;
        setupEndpoints();
    }

    private void setupEndpoints() {

        get("/user/:id", "application/json",(request, response)
                -> service.find(request.params(":id")), new JsonTransformer());

        get("/users", "application/json", (request, response)
                -> service.findAll(), new JsonTransformer());
    }
}

My service:

public class Service {

    public Object find(String id) {
        return null;
    }

    public Object findAll() {
        return null;
    }
}

My JsonTransformer:

import spark.ResponseTransformer;
public class JsonTransformer implements ResponseTransformer {
    @Override
    public String render(Object model) throws Exception {
        return null;
    }
}
like image 868
thebiggestlebowski Avatar asked Jan 24 '16 13:01

thebiggestlebowski


People also ask

What is a spark route?

In the Spark lingo, a route is a handler A route is a URL pattern that is mapped to a handler. A handler can be a physical file or a $ gradle run. We run the application with gradle run command. An embedded Jetty server is started. $ curl localhost:4567/hello Hello there!

Does spark use Jetty?

Spark is a compact framework for building web applications that run on the JVM. It comes with an embedded web server, Jetty, so you can get started in minutes.

Why use Spark Java?

Spark provides 100x faster processing speeds for applications because it stores the intermediate processing data in memory and does not have any read and write to disk unless you ask it to do. In the case, you asked it to use disk it acts 10x faster than regular technologies like Hadoop.

What is spark in Java?

Spark is a Java micro framework that allows to quickly create web applications in Java 8. Spark is a lightweight and simple Java web framework designed for quick development. Sinatra, a popular Ruby micro framework, was the inspiration for it.


2 Answers

You can set routes where you want. You just need call set up method in main thread. e.g.

 public static void main(String[] args){
     Resource resource= new Resource(new Service());
 }

 class Resource{

    private Service service;

    Resource(Service service){
      this.service = service;
      setupEndpoints();
    }

    private void setupEndpoints() {

      get("/user/:id", "application/json",(request, response)
            -> service.find(request.params(":id")), new JsonTransformer());

      get("/users", "application/json", (request, response)
            -> service.findAll(), new JsonTransformer());
    }
 }
like image 182
Andrew Avatar answered Sep 22 '22 14:09

Andrew


Here's a design idea you can use when there are multiple endpoints to configure:

First, create a builder interface:

public interface EndpointBuilder {
    void configure(Service spark, String basePath);
}

Now, let's say you have one of many other rest endpoints resources to set up:

public class CustomerEndpoint implements EndpointBuilder {

    private final CustomerService customerService;

    public CustomerEndpoint(CustomerService service) {
        this.customerService = service;
    }

    @Override
    public void configure(Service spark, String basePath) {

        spark.get(basePath + "/customer", (req, res) -> {
            return "hello";
        });
    }
}

Finally, create a RestContext class that will hold the spark instance and will enable you to configure whatever routes you wish:

public class RestContext {

    private static final Logger logger = LoggerFactory.getLogger(RestContext.class);

    private final Service spark;

    private final String basePath;

    public RestContext(int port, String basePath) {
        this.basePath = basePath;
        spark = Service.ignite().port(port); // import spark.Service;
    }

    public void addEndpoint(EndpointBuilder endpoint) {

        endpoint.configure(spark, basePath);
        logger.info("REST endpoints registered for {}.", endpoint.getClass().getSimpleName());
    }

    // Then you can even have some fun:
    public void enableCors() {

        spark.before((request, response) -> {
            response.header("Access-Control-Allow-Origin", "*");
            response.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            response.header("Access-Control-Allow-Headers", "Content-Type, api_key, Authorization");
        });

        logger.info("CORS support enabled.");
    }
}

You should be able to use this context class in your main method (and optionally in your test classes):

public static void main(String... args) {

    RestContext context = new RestContext(8080, "/api");

    context.addEndpoint(new CustomerEndpoint(new CustomerService()));
    context.addEndpoint(new AnotherEndpoint()); // you can add or remove as many as you want.

    context.enableCors();
}

Obs.: Since version 2.5, spark java supports multiple instances through the Service.ignite() api.

like image 39
juliaaano Avatar answered Sep 25 '22 14:09

juliaaano