RESTFul Service for GigaSpaces data using SparkJava
I came across SparkJava yesterday. It is a really interesting micro web framework especially for Java, where nothing really is micro and something like this is badly needed. Their website does a good job of explaining how it works and get started. I was up and running in minutes.
I build demos and proof of concepts as part of my job and always in the lookout for efficient and easier way to do things. The RESTful example caught my eye. I decided to extend this and show how you can expose data stored in GigaSpaces easily.
I created a maven web project using maven archetype:generate goal,
mvn -DgroupId=com.gigaspaces.spark -DartifactId=gs-spark -DarchetypeArtifactId=maven-archetype-webapp
I took the RESTful code mentioned above. As I want to run the RESTful service in GigaSpaces I changed the code to implement SparkApplication interface and define the Routes in the init() method.
I also created the web.xml as suggested here
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <filter> <filter-name>SparkFilter</filter-name> <filter-class>spark.servlet.SparkFilter</filter-class> <init-param> <param-name>applicationClass</param-name> <param-value>com.gigaspaces.spark.BooksService</param-value> </init-param> </filter> <filter-mapping> <filter-name>SparkFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
I modified the CRUD operations to go against a GigaSpace instead of a Map. Complete BooksService code is here,
package com.gigaspaces.spark;
import static spark.Spark.delete;
import static spark.Spark.get;
import static spark.Spark.post;
import static spark.Spark.put;
import java.util.Random;
import org.openspaces.core.GigaSpace;
import org.openspaces.core.GigaSpaceConfigurer;
import org.openspaces.core.space.UrlSpaceConfigurer;
import spark.Request;
import spark.Response;
import spark.Route;
import spark.servlet.SparkApplication;
public class BooksService implements SparkApplication {
/**
* Map holding the books
*/
private GigaSpace gigaSpace;
public void init() {
if (gigaSpace == null) {
gigaSpace = new GigaSpaceConfigurer(new UrlSpaceConfigurer(
"/./bookSpace").space()).gigaSpace();
}
// Creates a new book resource, will return the ID to the created
// resource
// author and title are sent as query parameters e.g.
// /books?author=Foo&title=Bar
post(new Route("/books") {
Random random = new Random();
@Override
public Object handle(Request request, Response response) {
String author = request.queryParams("author");
String title = request.queryParams("title");
Book book = new Book(author, title);
int id = random.nextInt(Integer.MAX_VALUE);
book.setId(id + "");
gigaSpace.write(book);
response.status(201); // 201 Created
return id;
}
});
// Gets the book resource for the provided id
get(new Route("/books/:id") {
@Override
public Object handle(Request request, Response response) {
Book template = new Book();
template.setId(request.params(":id"));
Book book = gigaSpace.read(template);
if (book != null) {
return "Title: " + book.getTitle() + ", Author: "
+ book.getAuthor();
} else {
response.status(404); // 404 Not found
return "Book not found";
}
}
});
// Updates the book resource for the provided id with new information
// author and title are sent as query parameters e.g.
// /books/<id>?author=Foo&title=Bar
put(new Route("/books/:id") {
@Override
public Object handle(Request request, Response response) {
String id = request.params(":id");
Book template = new Book();
template.setId(id);
Book book = gigaSpace.read(template);
if (book != null) {
String newAuthor = request.queryParams("author");
String newTitle = request.queryParams("title");
if (newAuthor != null) {
book.setAuthor(newAuthor);
}
if (newTitle != null) {
book.setTitle(newTitle);
}
gigaSpace.write(book);
return "Book with id '" + id + "' updated";
} else {
response.status(404); // 404 Not found
return "Book not found";
}
}
});
// Deletes the book resource for the provided id
delete(new Route("/books/:id") {
@Override
public Object handle(Request request, Response response) {
String id = request.params(":id");
Book template = new Book();
template.setId(id);
Book book = gigaSpace.take(template);
if (book != null) {
return "Book with id '" + id + "' deleted";
} else {
response.status(404); // 404 Not found
return "Book not found";
}
}
});
// Gets all available book resources (id's)
get(new Route("/books") {
@Override
public Object handle(Request request, Response response) {
String ids = "";
Book[] books = gigaSpace.readMultiple(new Book());
for (Book book:books)
ids = book.getId() + " " + ids;
return ids;
}
});
}
}For keeping it simple, I am creating GigaSpace inside the RESTful service/web container but in real applications you will be connecting to an external GigaSpace cluster which can be changed by updating the GigaSpace URL. For embedded space use "/./bookSpace" and for remote space use "jini://*/*/bookSpace" URL.
Source code is in the github repo here. README file has instructions on how to run this on your side.
As you can see, SparkJava seems to be a promising framework. Very simple configuration and code needed for building web apps.
Hope this helps others looking for building simple web apps in Java.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)




