mscharhag, Programming and Stuff;

A blog about programming and software development topics, mostly focused on Java technologies including Java EE, Spring and Grails.

  • Thursday, 5 June, 2014

    Building a simple RESTful API with Spark

    Disclaimer: This post is about the Java micro web framework named Spark and not about the data processing engine Apache Spark.

    In this blog post we will see how Spark can be used to build a simple web service. As mentioned in the disclaimer, Spark is a micro web framework for Java inspired by the Ruby framework Sinatra. Spark aims for simplicity and provides only a minimal set of features. However, it provides everything needed to build a web application in a few lines of Java code.

    Getting started with Spark

    Let's assume we have a simple domain class with a few properties and a service that provides some basic CRUD functionality:

    public class User {
    
      private String id;
      private String name;
      private String email;
      
      // getter/setter
    }
    public class UserService {
    
      // returns a list of all users
      public List<User> getAllUsers() { .. }
      
      // returns a single user by id
      public User getUser(String id) { .. }
    
      // creates a new user
      public User createUser(String name, String email) { .. }
    
      // updates an existing user
      public User updateUser(String id, String name, String email) { .. }
    }

    We now want to expose the functionality of UserService as a RESTful API (For simplicity we will skip the hypermedia part of REST ;-)). For accessing, creating and updating user objects we want to use following URL patterns:

    GET /users Get a list of all users
    GET /users/<id> Get a specific user
    POST /users Create a new user
    PUT /users/<id> Update a user

    The returned data should be in JSON format.

    To get started with Spark we need the following Maven dependencies:

    <dependency>
      <groupId>com.sparkjava</groupId>
      <artifactId>spark-core</artifactId>
      <version>2.0.0</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>1.7.7</version>
    </dependency>
    

    Spark uses SLF4J for logging, so we need to a SLF4J binder to see log and error messages. In this example we use the slf4j-simple dependency for this purpose. However, you can also use Log4j or any other binder you like. Having slf4j-simple in the classpath is enough to see log output in the console. We will also use GSON for generating JSON output and JUnit to write a simple integration tests. You can find these dependencies in the complete pom.xml.

    Returning all users

    Now it is time to create a class that is responsible for handling incoming requests. We start by implementing the GET /users request that should return a list of all users.

    import static spark.Spark.*;
    
    public class UserController {
    
      public UserController(final UserService userService) {
        
        get("/users", new Route() {
          @Override
          public Object handle(Request request, Response response) {
            // process request
            return userService.getAllUsers();
          }
        });
        
        // more routes
      }
    }

    Note the static import of spark.Spark.* in the first line. This gives us access to various static methods including get(), post(), put() and more. Within the constructor the get() method is used to register a Route that listens for GET requests on /users. A Route is responsible for processing requests. Whenever a GET /users request is made, the handle() method will be called. Inside handle() we return an object that should be sent to the client (in this case a list of all users).

    Spark highly benefits from Java 8 Lambda expressions. Route is a functional interface (it contains only one method), so we can implement it using a Java 8 Lambda expression. Using a Lambda expression the Route definition from above looks like this:

    get("/users", (req, res) -> userService.getAllUsers());

    To start the application we have to create a simple main() method. Inside main() we create an instance of our service and pass it to our newly created UserController:

    public class Main {
      public static void main(String[] args) {
        new UserController(new UserService());
      }
    }

    If we now run main(), Spark will start an embedded Jetty server that listens on Port 4567. We can test our first route by initiating a GET http://localhost:4567/users request. 
    In case the service returns a list with two user objects the response body might look like this:

    [com.mscharhag.sparkdemo.User@449c23fd, com.mscharhag.sparkdemo.User@437b26fe]

    Obviously this is not the response we want.

    Spark uses an interface called ResponseTransformer to convert objects returned by routes to an actual HTTP response. ReponseTransformer looks like this:

    public interface ResponseTransformer {
      String render(Object model) throws Exception;
    }

    ResponseTransformer has a single method that takes an object and returns a String representation of this object. The default implementation of ResponseTransformer simply calls toString() on the passed object (which creates output like shown above).

    Since we want to return JSON we have to create a ResponseTransformer that converts the passed objects to JSON. We use a small JsonUtil class with two static methods for this:

    public class JsonUtil {
    
      public static String toJson(Object object) {
        return new Gson().toJson(object);
      }
    
      public static ResponseTransformer json() {
        return JsonUtil::toJson;
      }
    }

    toJson() is an universal method that converts an object to JSON using GSON. The second method makes use of Java 8 method references to return a ResponseTransformer instance. ResponseTransformer is again a functional interface, so it can be satisfied by providing an appropriate method implementation (toJson()). So whenever we call json() we get a new ResponseTransformer that makes use of our toJson() method.

    In our UserController we can pass a ResponseTransformer as a third argument to Spark's get() method:

    import static com.mscharhag.sparkdemo.JsonUtil.*;
    
    public class UserController {
      
      public UserController(final UserService userService) {
        
        get("/users", (req, res) -> userService.getAllUsers(), json());
        
        ...
      }
    }

    Note again the static import of JsonUtil.* in the first line. This gives us the option to create a new ResponseTransformer by simply calling json().
    Our response looks now like this:

    [{
      "id": "1866d959-4a52-4409-afc8-4f09896f38b2",
      "name": "john",
      "email": "john@foobar.com"
    },{
      "id": "90d965ad-5bdf-455d-9808-c38b72a5181a",
      "name": "anna",
      "email": "anna@foobar.com"
    }]

    We still have a small problem. The response is returned with the wrong Content-Type. To fix this, we can register a Filter that sets the JSON Content-Type:

    after((req, res) -> {
      res.type("application/json");
    });

    Filter is again a functional interface and can therefore be implemented by a short Lambda expression. After a request is handled by our Route, the filter changes the Content-Type of every response to application/json. We can also use before() instead of after() to register a filter. Then, the Filter would be called before the request is processed by the Route.

    The GET /users request should be working now :-)

    Returning a specific user

    To return a specific user we simply create a new route in our UserController:

    get("/users/:id", (req, res) -> {
      String id = req.params(":id");
      User user = userService.getUser(id);
      if (user != null) {
        return user;
      }
      res.status(400);
      return new ResponseError("No user with id '%s' found", id);
    }, json());

    With req.params(":id") we can obtain the :id path parameter from the URL. We pass this parameter to our service to get the corresponding user object. We assume the service returns null if no user with the passed id is found. In this case, we change the HTTP status code to 400 (Bad Request) and return an error object.

    ResponseError is a small helper class we use to convert error messages and exceptions to JSON. It looks like this:

    public class ResponseError {
      private String message;
    
      public ResponseError(String message, String... args) {
        this.message = String.format(message, args);
      }
    
      public ResponseError(Exception e) {
        this.message = e.getMessage();
      }
    
      public String getMessage() {
        return this.message;
      }
    }

    We are now able to query for a single user with a request like this:
    GET /users/5f45a4ff-35a7-47e8-b731-4339c84962be
    If an user with this id exists we will get a response that looks somehow like this:

    {
      "id": "5f45a4ff-35a7-47e8-b731-4339c84962be",
      "name": "john",
      "email": "john@foobar.com"
    }

    If we use an invalid user id, a ResponseError object will be created and converted to JSON. In this case the response looks like this:

    {
      "message": "No user with id 'foo' found"
    }

    Creating and updating user with Spark

    Creating and updating users is again very easy. Like returning the list of all users it is done using a single service call:

    post("/users", (req, res) -> userService.createUser(
        req.queryParams("name"),
        req.queryParams("email")
    ), json());
    
    put("/users/:id", (req, res) -> userService.updateUser(
        req.params(":id"),
        req.queryParams("name"),
        req.queryParams("email")
    ), json());

    To register a route for HTTP POST or PUT requests we simply use the static post() and put() methods of Spark. Inside a Route we can access HTTP POST parameters using req.queryParams().
    For simplicity reasons (and to show another Spark feature) we do not do any validation inside the routes. Instead we assume that the service will throw an IllegalArgumentException if we pass in invalid values.

    Spark gives us the option to register ExceptionHandlers. An ExceptionHandler will be called if an Exception is thrown while processing a route. ExceptionHandler is another single method interface we can implement using a Java 8 Lambda expression:

    exception(IllegalArgumentException.class, (e, req, res) -> {
      res.status(400);
      res.body(toJson(new ResponseError(e)));
    });

    Here we create an ExceptionHandler that is called if an IllegalArgumentException is thrown. The caught Exception object is passed as the first parameter. We set the response code to 400 and add an error message to the response body.

    If the service throws an IllegalArgumentException when the email parameter is empty, we might get a response like this:

    {
      "message": "Parameter 'email' cannot be empty"
    }

    The complete source the controller can be found here.

    Testing with Spark

    Because of Spark's simple nature it is very easy to write integration tests for our sample application.
    Let's start with this basic JUnit test setup:

    public class UserControllerIntegrationTest {
    
      @BeforeClass
      public static void beforeClass() {
        Main.main(null);
      }
    
      @AfterClass
      public static void afterClass() {
        Spark.stop();
      }
      
      ...
    }

    In beforeClass() we start our application by simply running the main() method. After all tests finished we call Spark.stop(). This stops the embedded server that runs our application.

    After that we can send HTTP requests within test methods and validate that our application returns the correct response. A simple test that sends a request to create a new user can look like this:

    @Test
    public void aNewUserShouldBeCreated() {
      TestResponse res = request("POST", "/users?name=john&email=john@foobar.com");
      Map<String, String> json = res.json();
      assertEquals(200, res.status);
      assertEquals("john", json.get("name"));
      assertEquals("john@foobar.com", json.get("email"));
      assertNotNull(json.get("id"));
    }

    request() and TestResponse are two small self made test utilities. request() sends a HTTP request to the passed URL and returns a TestResponse instance. TestResponse is just a small wrapper around some HTTP response data. The source of request() and TestResponse is included in the complete test class found on GitHub.

    Conclusion

    Compared to other web frameworks Spark provides only a small amount of features. However, it is so simple you can build small web applications within a few minutes (even if you have not used Spark before). If you want to look into Spark you should clearly use Java 8, which reduces the amount of code you have to write a lot.

    You can find the complete source of the sample project on GitHub.

  • Saturday, 24 May, 2014

    Java File I/O Basics

    Java 7 introduced the java.nio.file package to provide comprehensive support for file I/O. Besides a lot of other functionality this package includes the Files class (if you already use this class you can stop reading here). Files contains a lot of static methods that can be used to accomplish common tasks when working with files. Unfortunately it looks to me that still a lot of newer (Java 7+) code is written using old (pre Java 7) ways of working with files. This does not have to be bad, but it can make things more complex than needed. A possible reason for this might be that a lot of articles and high rated Stackoverflow answers were written before the release of Java 7.

    In the rest of this post I will provide some code samples that show how you can accomplish common file related tasks with Java 7 or newer.

    Working with files in Java

    // Create directories
    // This will create the "bar" directory in "/foo"
    // If "/foo" does not exist, it will be created first
    Files.createDirectories(Paths.get("/foo/bar"));
    
    // Copy a file
    // This copies the file "/foo/bar.txt" to "/foo/baz.txt"
    Files.copy(Paths.get("/foo/bar.txt"), Paths.get("/foo/baz.txt"));
    
    // Move a file
    // This moves the file "/foo/bar.txt" to "/foo/baz.txt"
    Files.move(Paths.get("/foo/bar.txt"), Paths.get("/foo/baz.txt"));
    
    // Delete a file
    Files.delete(Paths.get("/foo/bar.txt"));
    
    // Delete a file but do not fail if the file does not exist
    Files.deleteIfExists(Paths.get("/foo/bar.txt"));
    
    // Check if a file exists
    boolean exists = Files.exists(Paths.get("/foo/bar.txt"));

    Most methods of Files take one or more arguments of type Path. Path instances represent a path to a file or directory and can be obtained using Paths.get(). Note that most methods shown here also have an additional varargs parameter that can be used to pass additional options.

    For example:

    Files.copy(Paths.get("/foo.txt"), Paths.get("/bar.txt"), StandardCopyOption.REPLACE_EXISTING);

    Iterating through all files within a directory

    Files.walkFileTree(Paths.get("/foo"), new SimpleFileVisitor<Path>() {
      @Override
      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        System.out.println("file: " + file);
        return FileVisitResult.CONTINUE;
      }
    });

    Here the visitFile() method will be called for every file within the /foo directory. You can override additional methods of SimpleFileVisitor if you want to track directories too.

    Writing and reading files

    // Write lines to file
    List<String> lines = Arrays.asList("first", "second", "third");
    Files.write(Paths.get("/foo/bar.txt"), lines, Charset.forName("UTF-8"));
    
    // Read lines
    List<String> lines = Files.readAllLines(Paths.get("/foo/bar.txt"), Charset.forName("UTF-8"));

    The shown methods work with characters. Similar methods are available if you need to work with bytes.

    Conclusion

    If you didn't know about java.nio.file.Files you should definitely have a look at the Javadoc method summary. There is a lot of useful stuff inside.

  • Saturday, 10 May, 2014

    Grails: The Tomcat kill switch

    Some time ago we had some strange effects when running an application in our local development environment. It turned out that the cause of these effects was a feature of the Grails Tomcat plugin.

    The actual application consists out of two different Grails applications. To run both Grails applications at the same time on our local machines we configured two different application ports. The first application (let's call it App1) was running on Port 8081 while App2 (the second application) was running on Port 8082.

    Now we faced the following effects:

    • If App2 was started before App1 everything worked fine. However, if App1 was started first, then App2 would not start and show a "Port is already in use" error instead. What?!
    • App1 contains links that point to App2. For our local environment these links look like http://localhost:8082/app2/someController. If App2 was not started at all and someone clicked one of these links App1 stopped working. What?!

    After some research it turned out, that the reason for this is the TomcatKillSwitch provided by the Tomcat plugin. This class starts a server socket that listens on serverPort + 1. If something is send to this port the embedded tomcat is shut down.

    So whenever we started App1 first the kill switch was listening at port 8082 (and therefore we were not able to start App2). Clicking any link that points to App2 triggered the kill switch and the embedded Tomcat of App1 shuts down. If we started App2 first the server socket of the kill switch failed silently on startup of App1 and everything worked as expected. Changing the port of App2 from 8082 to 8083 solved the problem.

  • Thursday, 8 May, 2014

    Grails Controller namespaces

    Grails 2.3 introduced controller namespaces. This feature gives Grails developers the option to have multiple controllers that use the same name (within different packages).

    It is not that hard to get into a situation where you want two or more controllers with the same name.
    Assume we have an application that gives users the option to update their personal profile settings. We might have a ProfileController for this. Now we might also need an administration backend which gives administrators the option to update user profiles. ProfileController would again be a good name for handling these kinds of requests.

    With Grails 2.3 we can now do this by adding namespaces to controllers using the static namespace property:
    package foo.bar.user
    
    class ProfileController {
    
      static namespace = 'user'
    
      // actions that can be accessed by users
    }
    package foo.bar.admin
    
    class ProfileController {
    
      static namespace = 'admin'
    
      // actions that can be accessed by administrators
    }
    We can now use the namespace to map the controllers to different URLs within UrlMappings.groovy:
    class UrlMappings {
    
      static mappings = { 
        '/profile' { 
          controller = 'profile' 
          namespace = 'user' 
        }
        '/admin/profile' { 
          controller = 'profile' 
          namespace = 'admin' 
        }
        ..
      }
    }
    To make the namespace part of the URL by default we can use the $namespace variable:
    static mappings = { 
      "/$namespace/$controller/$action?"() 
    }
    Using this way we are able to access our controllers with the following URLs:

    /user/profile/<action>
    /admin/profile/<action>

    Please note that we also need to provide the namespace when building links:
    <g:link controller="profile" namespace="admin">Profile admin functions</g:link>
  • Thursday, 17 April, 2014

    Groovy 2.3 introduces traits

    A few days ago the second beta of Groovy 2.3 got released. One of the major new Groovy 2.3 features are traits. A trait is a reusable set of methods and fields that can be added to one or more classes. A class can be composed out of multiple traits without using multiple inheritance (and therefore avoiding the diamond problem).

    Basic usage of Groovy Traits

    The following piece of code shows a basic definition of a trait in Groovy 2.3.

    trait SwimmingAbility {
      def swim() {
        println "swimming.."
      }
    }

    A trait definition looks very similar to a class definition. This trait defines a single method swim(). We can add this trait to a class using the implements keyword:

    class Goldfish implements SwimmingAbility {
      ..
    }

    Now we are able to call the swim() methods on Goldfish objects:

    def goldfish = new Goldfish()
    goldfish.swim()

    So far we could have accomplished the same using inheritance. The difference is that we can add multiple traits to a single class. So let's define another trait:

    trait FlyingAbility {
      def fly() {
        println "flying.."
      }
    }

    We can now create a new class that makes use of both traits:

    class Duck implements SwimmingAbility, FlyingAbility {
      ..
    }

    Ducks can swim and fly now:

    def duck = new Duck()
    duck.swim()
    duck.fly()

    this inside traits

    Inside traits the this keyword represents the implementing instance. This means you can write the following:

    trait FlyingAbility {
      def fly() {
        println "${this.class.name} is flying.."
      }
    }

    In case of the Duck class from above this will print

    Duck is flying..

    if we call duck.fly().

    A more complex example

    Now let's look at an example that shows some more features of Groovy traits

    trait Trader {
    
      int availableMoney = 0
      private int tradesDone = 0
    
      def buy(Item item) {
        if (item.price <= availableMoney) {
          availableMoney -= item.price
          tradesDone += 1
          println "${getName()} bought ${item.name}"
        }
      }
    
      def sell(Item item) {
        ..
      }
    
      abstract String getName()
    }

    Like Groovy classes traits support properties. Here the property availableMoney will become private and public getter / setter methods will be generated. These methods can be accessed on implementing classes. tradesDone is a private variable that cannot be accessed outside the Trader trait. Within this trait we defined an abstract method getName(). This method has to be implemented by classes that make use of this trait.

    Let's create a class that implements our Trader trait:

    class Merchant implements Trader {
      
      String name
    
      String getName() {
        return this.name
      }
    }

    A Merchant is now be able to buy items:

    def bike = new Item(name: 'big red bike', price: 750)
    def paul = new Merchant(name: 'paul')
    
    paul.availableMoney = 2000
    paul.buy(bike) // prints "paul bought big red bike"
    
    println paul.availableMoney // 1250

    Extending from traits, Overriding and conflict resolution

    A trait can inherit functionality from another trait using the extends keyword:

    trait Dealer {
      def getProfit() { ... }
      def deal() { ... }
    }
    
    trait CarDealer extends Dealer {
      def deal() { ... }
    }

    Here the CarDealer trait extends Dealer and overrides the deal() method of Dealer.

    Trait methods can also be overwritten in implementing classes:

    class OnlineCarDealer implements CarDealer {
      def deal() { ... }
    }

    If a class implements more than one trait it is possible to create a conflict. That's the case if two or more traits define a method with an identical signature:

    trait Car {
      def drive() { ... }
    }
    
    trait Bike {
      def drive() { ... }
    }
    
    class DrivingThing implements Car, Bike { ... }

    In such a situation the last declared trait wins (Bike in this example).

    Conclusion

    I think traits are a very useful concept and I am happy to see them in Groovy. Other than Groovy mixins traits work at compile time and can therefore be accessed from Java code. For further reading I can recommend the Groovy 2.3 Trait documentation.