Skip to content

Instantly share code, notes, and snippets.

@jeantessier
Last active Sep 5, 2015
Embed
What would you like to do?
Replace complicated Java microservice with trivial Grails 3 app.
package springpack.model
import grails.rest.*
@Resource(uri='/users', formats=['json', 'xml'])
class User {
String username
String email
}
@jeantessier

This comment has been minimized.

Copy link
Owner Author

@jeantessier jeantessier commented Aug 14, 2015

An InfoQ article was showing how to build a microservice in Java with Ratpack and Spring Boot.

I was surprised at how much boilerplate there was. The Gradle project file, the entity file with all the Hibernate annotations, and the Main class with all the crazy, custom, manual routing.

I was able to recreate it all just by creating an empty Grails 3 project and adding a single domain object that is much, much shorter. It duplicates the Ratpack app completely, down to using H2 for its in-memory database.

List users with:

curl http://localhost:8080/users/

Create a user with:

curl \
    -X POST \
    -H 'Content-Type: application/json' \
    http://localhost:8080/users/ \
    -d '{"username": "Jean Tessier", "email": "jean@jeantessier.com"}'

Show a user with:

curl http://localhost:8080/users/1

Update a user with:

curl \
    -X POST \
    -H 'Content-Type: application/json' \
    http://localhost:8080/users/1 \
    -d '{"email": "info@sanmateokendo.org"}'

Delete a user with:

curl \
    -X DELETE \
    -H 'Content-Type: application/json' \
    http://localhost:8080/users/1
@jeantessier

This comment has been minimized.

Copy link
Owner Author

@jeantessier jeantessier commented Aug 14, 2015

Now that I think about it, there are two noticeable differences between the Ratpack implementation in the article and my Grails implementation:

  1. The article's implementation extracts username from the path of the URL to lookup records. By default, Grails uses a numerical id. I could tell it to use username as the ID for User, and then it would work just like in the article.

    class User {
        ...
        static mapping = {
            version false
            id column: 'username'
        }
    }

    This example also removes the default version field that Grails adds automatically, just to be closer to the article's data structure.

  2. Ratpack uses a non-blocking HTTP server instead of the servlet-based one in Grails. I hear that these non-blocking servers, like the one in node.js, are much more resource efficient than connection-based ones like servlets.

    The Grails documentation mentions support for asynchronous responses.

    Since Grails 2.3, Grails features a simplified API for creating asynchronous responses [...]. The implementation is based on Servlet 3.0 async [...]

    From what I am reading, I would have to write a custom controller. Grails has it's own variation on Promises. The resulting controller would still be significantly more focused than the Main class from the article.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment