Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

REST With Lambdas and Wicket 8

DZone's Guide to

REST With Lambdas and Wicket 8

Lambdas provide amazing benefits when it comes to creating custom resources. With Wicket 8, we can build a custom resource with a simple lambda expression.

· Integration Zone
Free Resource

Share, secure, distribute, control, and monetize your APIs with the platform built with performance, time-to-value, and growth in mind. Free 90-day trial of 3Scale by Red Hat

The year 2016 will undoubtedly be remembered as the year Java 8 became mainstream. After more than two years since its release, Java 8 has seen a massive adoption, and many frameworks have fully embraced the last Java version with all its groundbreaking features (lambdas and streams in particular). I and other core developers are putting the final touches on the incoming version 8 of Wicket, which will benefit from full adoption of Java 8. Many of the features that you will find in Wicket 8 were unveiled at last ApacheCon Europe in Sevilla by Martijn Dashorst during his presentation.

In this article, we will focus on the huge benefits that lambdas bring when we want to create a custom resource. As we know, a Wicket resource implements the functional interface org.apache.wicket.request.resource.IResource, so with Wicket 8, we can build a custom resource with a simple lambda expression:

IResource res = (attributes) -> attributes.getResponse().write("ciao!");

This is a huge improvement over the pre-Java 8 code, where we had to use a separate class or an anonymous one. In the user guide, you can see a full example for using a custom resource with Wicket 8.

This is just the tip of the iceberg. With a little more effort, it was possible to create a tiny utility library that could be used to write REST services with lambda expressions, just like we use to do with frameworks like Spark or Rapidoid. The library is part of the WicketStuff project and it will be available with the final release of Wicket 8. In the meantime, we can use the snapshot version using the following repository and dependency definitions (for Maven):  

<repository>
    <id>wicketstuff-snapshot</id>
    <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    <snapshots>
        <enabled>true</enabled>
    </snapshots>        
</repository>

...

<dependency>
    <groupId>org.wicketstuff</groupId>
    <artifactId>wicketstuff-rest-lambda</artifactId>
    <version>8.0.0-SNAPSHOT</version>
</dependency>

When we are done with configuration stuff, we can mount our REST resources in our Wicket application using class LambdaRestMounter:

@Override
public void init()
{
    super.init();

    LambdaRestMounter mounter = new LambdaRestMounter(this);
    mounter.get("/", (attributes) -> attributes.getWebResponse().write("bravo!"));
}

A REST service can be implemented with a simple lambda consumer that takes in input an instance of AttributesWrapper. This class provides access to the current request and response and to other useful information (for example, URL segment value, query string parameters, etc.).

Since REST services are usually meant to generate a textual output, we can also define them by providing two functions: one to produce a generic result and another one to convert the result into text. As with the converter function, we can use a method reference to the JSON library like we did in the following example:

@Override
protected void init()
{
    Map<String, Object> map = new HashMap<>();
    map.put("integer", 123);
    map.put("string", "message");

    //Jackson JSON converter
    ObjectMapper mapper = new ObjectMapper();

    LambdaRestMounter restMounter = new LambdaRestMounter(this);

    //specify a function to transform the returned object into text (json in this case)
    restMounter.post("/testjson", (attributes) -> map, mapper::writeValueAsString);
}

REST resources created with LambdaRestMounter can take full advantage of the Wicket mounting mechanism. Hence, we can use parameter placeholders in the URL that we want to use:

@Override
protected void init()
{
  //return id value from url segment
  restMounter.options("/testparam/${id}", (attributes) -> {
    PageParameters pageParameters = attributes.getPageParameters();
    return pageParameters.get("id");
  }
  , Object::toString);
}

The code of the library is available on GitHub. Feel free to contribute with a pull request or opening an issue.

Explore the core elements of owning an API strategy and best practices for effective API programs. Download the API Owner's Manual, brought to you by 3Scale by Red Hat

Topics:
wicket ,rest ,lambdas ,integration ,java 8

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}