This Week in Spring - September 22nd, 2015

Engineering | Josh Long | September 22, 2015 | ...

Welcome to another installment of This Week in Spring! This week, fresh after an incredible SpringOne2GX 2015, I'm.. a little burnt if I'm honest! :D BUT, Spring endures and I'm this week in Amsterdam with our pal Martin Deinum helping a large group of developers make the cloud native journey with Spring Boot, Spring Cloud and Cloud Foundry.

Java DSL for Spring Integration 1.1 GA is Available

Engineering | Artem Bilan | September 22, 2015 | ...

Dear Spring Community!

On behalf of Spring Integration team I'm pleased to announce that the 1.1 GA of Spring Integration Java DSL is now available from the Release Repository and Maven Central:

For Gradle use this dependency:

'org.springframework.integration:spring-integration-java-dsl:1.1.0.RELEASE'

For Maven this:

<dependency>
     <groupId>org.springframework.integration</groupId>
     <artifactId>spring-integration-java-dsl</artifactId>
     <version>1.1.0.RELEASE</version>
</dependency>

First of all a big thanks to everyone who visited my talk at the SpringOne 2GX 2015 last week…

Spring for Apache Hadoop 2.3 Milestone 3 released

Releases | Thomas Risberg | September 22, 2015 | ...

We are pleased to announce the Spring for Apache Hadoop 2.3 M3 milestone release.

The most important enhancements in this release:

  • Update build to use Spring Framework 4.2.1, Boot 1.3.0.M5, Batch 3.0.5 [SHDP-509]
  • Move annotation config to separate sub-project to reduce dependencies for spring-data-hadoop-boot [SHDP-525]
  • Add additional properties to Spark Tasklet [SHDP-397]
  • Upgrade build to use to Spark 1.5.0 [SHDP-521]

See the release changelog for details.

We continue to provide version specific artifacts with their respective transitive dependencies in the Spring IO milestone repository:

  • 2.3.0.M3 (default - Apache Hadoop stable 2.7.1)
  • 2.3.0.M3-hadoop26 (Apache Hadoop 2.6.0)
  • 2.3.0.M3-phd30 (Pivotal HD 3.0)
  • 2.3.0.M3-phd21 (Pivotal HD 2.1)
  • 2.3.0.M3-cdh5 (Cloudera CDH 5.4)
  • 2.3.0.M3-hdp23 (Hortonworks HDP 2.3)

Single-page web apps with Vaadin Spring 1.0

Engineering | Stéphane Nicoll | September 17, 2015 | ...

This post is a guest post by community member Matti Tahvonen (@MattiTahvonen), who works as a developer advocate in Vaadin Ltd, the company that originally developed Vaadin Framework and provides commercial services and extensions for it.

The Spring integration library for Vaadin has been in beta stage since May and has already been used by several production applications. Today we are proud to announce that the beta flag is dropped and the stable 1.0.0 release is out.

Vaadin is a component based web UI framework where your application state and logic lives in the memory of your Java…

First Milestone of Spring Cloud Brixton Release Train is Available

Releases | Spencer Gibb | September 16, 2015 | ...

On behalf of the Spring Cloud team, I am pleased to announce the first milestone of the Spring Cloud Brixton release train. The milestone is available today and can be found in our Spring Milestone repository. We’ve made numerous enhancements and bug fixes, some of the highlights include:

  • Spring Boot 1.3.x and Spring 4.2.x support
  • Cluster Leadership election and locks
  • Hashicorp Consul support for service registration/discovery, configuration and bus
  • Apache Zookeeper support for service registration/discovery, configuration and leader election
  • Lattice support for service registration/discovery
  • Distributed tracing support

This Week in Spring - September 15th, 2015 - SpringOne2GX 2015 edition!

Engineering | Josh Long | September 16, 2015 | ...

Welcome to another installment of This Week in Spring! This week, we're in beautiful Washington DC for the amazing SpringOne2GX 2015!

It's been an amazing event packed with amazing, pivotal moments that saw more than a thousand attendees - including engineers from some of the largest websites in the world - Rakuten, Alibaba, and Netflix, among others - join us here in Washington DC to learn and love what Pivotal is doing with and around Spring.

Here are some of my favorite moments:

get cloud native

  • this year saw Pivotal take cloud-native further and faster than anyone and SpringOne2GX has been a huge celebration of this drive: GET CLOUD NATIVE.

React.js and Spring Data REST: Part 2 - Hypermedia

Engineering | Greg L. Turnquist | September 15, 2015 | ...
To see updates to this code, visit our React.js and Spring Data REST tutorial.

In the previous session, you found out how to stand up a backend payroll service to store employee data using Spring Data REST. A key feature it lacked was using the hypermedia controls and navigation by links. Instead, it hard coded the path to find data.

Feel free to grab the code from this repository and follow along. This session is based on the previous session’s app with extra things added.

In the beginning there was data…​and then there was REST

I am getting frustrated by the number of people calling any HTTP-based interface a REST API. Today’s example is the SocialSite REST API. That is RPC. It screams RPC…​.What needs to be done to make the REST architectural style clear on the notion that hypertext is a constraint? In other words, if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API. Period. Is there some broken manual somewhere that needs to be fixed?

So, what exactly ARE hypermedia controls, i.e. hypertext, and how can you use them? To find out, let’s take a step back and look at the core mission of REST.

The concept of REST was to borrow ideas that made the web so successful and apply them to APIs. Despite the web’s vast size, dynamic nature, and low rate that clients, i.e. browsers, are updated, the web is an amazing success. Roy Fielding sought to use some of its constraints and features and see if that would afford similar expansion of API production and consumption.

One of the constraints is to limit the number of verbs. For REST, the primary ones are GET, POST, PUT, DELETE, and PATCH. There are others, but we won’t get into them here.

  • GET - fetch the state of a resource without altering the system
  • POST - create a new resource without saying where
  • PUT - replace an existing resource, overwriting whatever else is already there (if anything)
  • DELETE - remove an existing resource
  • PATCH - alter an existing resource partially

These are standardized HTTP verbs with well written specs. By picking up and using already coined HTTP operations, we don’t have to invent a new language and educate the industry.

Another constraint of REST is to use media types to define the format of data. Instead of everyone writing their own dialect for the exchange of information, it would be prudent to develop some media types. One of the most popular ones to be accepted is HAL, media type application/hal+json. It is Spring Data REST’s default media type. A keen value is that there is no centralized, single media type for REST. Instead, people can develop media types and plug them in. Try them out. As different needs become available, the industry can flexibly move.

A key feature of REST is to include links to relevant resources. For example, if you were looking at an order, a RESTful API would include a link to the related customer, links to the catalog of items, and perhaps a link to the store from which the order was placed. In this session, you will introduce paging, and see how to also use navigational paging links.

Turning on paging from the backend

To get underway with using frontend hypermedia controls, you need to turn on some extra controls. Spring Data REST provides paging support. To use it, just tweak the repository definition:

src/main/java/com/greglturnquist/payroll/EmployeeRepository.java
public interface EmployeeRepository extends PagingAndSortingRepository<Employee, Long> {

}

Your interface now extends PagingAndSortingRepository which adds extra options to set page size, and also adds navigational links to hop from page to page. The rest of the backend is the same (exception for some extra pre-loaded data to make things interesting).

Restart the application (./mvnw spring-boot:run) and see how it works.

$ curl localhost:8080/api/employees?size=2
{
  "_links" : {
    "first" : {
      "href" : "http://localhost:8080/api/employees?page=0&size=2"
    },
    "self" : {
      "href" : "http://localhost:8080/api/employees"
    },
    "next" : {
      "href" : "http://localhost:8080/api/employees?page=1&size=2"
    },
    "last" : {
      "href" : "http://localhost:8080/api/employees?page=2&size=2"
    }
  },
  "_embedded" : {
    "employees" : [ {
      "firstName" : "Frodo",
      "lastName" : "Baggins",
      "description" : "ring bearer",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/api/employees/1"
        }
      }
    }, {
      "firstName" : "Bilbo",
      "lastName" : "Baggins",
      "description" : "burglar",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/api/employees/2"
        }
      }
    } ]
  },
  "page" : {
    "size" : 2,
    "totalElements" : 6,
    "totalPages" : 3,
    "number" : 0
  }
}

The default page size is 20, so to see it in action, ?size=2 applied. As expected, only two employees are listed. In addition, there is also a first, next, and last link. There is also the self link, free of context including page parameters.

If you navigate to the next link, you’ll then see a prev link as well:

$ curl "http://localhost:8080/api/employees?page=1&size=2"
{
  "_links" : {
    "first" : {
      "href" : "http://localhost:8080/api/employees?page=0&size=2"
    },
    "prev" : {
      "href" : "http://localhost:8080/api/employees?page=0&size=2"
    },
    "self" : {
      "href" : "http://localhost:8080/api/employees"
    },
    "next" : {
      "href" : "http://localhost:8080/api/employees?page=2&size=2"
    },
    "last" : {
      "href" : "http://localhost:8080/api/employees?page=2&size=2"
    }
  },
...
Note
When using "&" in URL query parameters, the command line thinks it’s a line break. Wrap the whole URL with quotation marks to bypass that.

That looks neat, but it will be even better when you update the frontend to take advantage of that.

Navigating by relationship

That’s it! No more changes are needed on the backend to start using the hypermedia controls Spring Data REST provides out of the box. You can switch to working on the frontend. (That’s part of the beauty of Spring Data REST. No messy controller updates!)

Note
It’s important to point out, this application isn’t "Spring Data REST-specific." Instead, it uses HAL, URI Templates, and other standards. That’s how using rest.js is a snap: that library comes with HAL support.

In the previous session, you hardcoded the path to /api/employees. Instead, the ONLY path you should hardcode is the root.

...
var root = '/api';
...

With a handy little follow() function, you can now start from the root and navigate to where you need!

componentDidMount: function () {
    this.loadFromServer(this.state.pageSize);
},

In the previous session, the loading was done directly inside componentDidMount(). In this session, we are making it possible to reload the entire list of employees when the page size is updated. To do so, we have moved things into loadFromServer().

loadFromServer: function (pageSize) {
    follow(client, root, [
        {rel: 'employees', params: {size: pageSize}}]
    ).then(employeeCollection => {
        return client({
            method: 'GET',
            path: employeeCollection.entity._links.profile.href,
            headers: {'Accept': 'application/schema+json'}
        }).then(schema => {
            this.schema = schema.entity;
            return employeeCollection;
        });
    }).done(employeeCollection => {
        this.setState({
            employees: employeeCollection.entity._embedded.employees,
            attributes: Object.keys(this.schema.properties),
            pageSize: pageSize,
            links: employeeCollection.entity._links});
    });
},

loadFromServer is very similar the previous session, but instead if uses follow():

  • The first argument to the follow() function is the client object used to make REST calls.
  • The second argument is the root URI to start from.
  • The third argument is an array of relationships to navigate along. Each one can be a string or an object.

The array of relationships can be as simple as ["employees"], meaning when the first call is made, look in _links for the relationship (or rel) named employees. Find its href and navigate to it. If there is another relationship in the array, rinse and repeat.

Sometimes, a rel by itself isn’t enough. In this fragment of code, it also plugs in a query parameter of ?size=<pageSize>. There are other options that can be supplied, as you’ll see further along.

Grabbing JSON Schema metadata

After navigating to employees with the size-based query, the employeeCollection is at your fingertips. In the previous session, we called it day and displayed that data inside <EmployeeList />. Today, you are performing another call to grab some JSON Schema metadata found a /api/profile/employees.

You can see the data yourself:

$ curl http://localhost:8080/api/profile/employees -H 'Accept:application/schema+json'
{
  "title" : "Employee",
  "properties" : {
    "firstName" : {
      "title" : "First name",
      "readOnly" : false,
      "type" : "string"
    },
    "lastName" : {
      "title" : "Last name",
      "readOnly" : false,
      "type" : "string"
    },
    "description" : {
      "title" : "Description",
      "readOnly" : false,
      "type" : "string"
    }
  },
  "definitions" : { },
  "type" : "object",
  "$schema" : "http://json-schema.org/draft-04/schema#"
}
Note
The default form of metadata at /profile/employees is ALPS. In this case, though, you are using content negotation to fetch JSON Schema.

By capturing this information in the`<App />` component’s state, you can make good use of it later on when building input forms.

Creating new records

Equipped with this metadata, you can now add some extra controls to the UI. Create a new React component, <CreateDialog />.

var CreateDialog = React.createClass({
handleSubmit: function (e) {
    e.preventDefault();
    var newEmployee = {};
    this.props.attributes.forEach(attribute =&gt; {
        newEmployee[attribute] = React.findDOMNode(this.refs[attribute]).value.trim();
    });
    this.props.onCreate(newEmployee);

    // clear out the dialog's inputs
    this.props.attributes.forEach(attribute =&gt; {
        React.findDOMNode(this.refs[attribute]).value = '';
    });

    // Navigate away from the dialog to hide it.
    window.location = "#";
},

render: function () {
    var inputs = this.props.attributes.map(attribute…

Spring AMQP 1.5.0 Release Available

Releases | Gary Russell | September 10, 2015 | ...

We are pleased to announce that the 1.5.0.RELEASE of Spring AMQP is now available.

See the release notes for a few changes that have been applied since the release candidate was announced.

See the release candidate announcement and the reference document what's new for complete details of the release content.

See the project page for links to downloads, documentation etc. ##SpringOne 2GX 2015 is around the corner! Book your place at SpringOne2GX in Washington, DC next week. It’s simply the best opportunity to find out first hand all that’s going on and to provide direct feedback.

Spring Integration 4.2 Release is Available

Releases | Gary Russell | September 10, 2015 | ...

We are pleased to announce that the 4.2.0.RELEASE of Spring Integration is now available.

See the release notes for a few changes that have been applied since the release candidate was announced.

See the release candidate announcement and the reference document what's new for complete details of the release content.

See the project page for links to downloads, documentation etc.

##SpringOne 2GX 2015 is around the corner! Book your place at SpringOne2GX in Washington, DC next week. It’s simply the best opportunity to find out first hand all that’s going on and to provide direct feedback.

Get the Spring newsletter

Stay connected with the Spring newsletter

Subscribe

Get ahead

VMware offers training and certification to turbo-charge your progress.

Learn more

Get support

Tanzu Spring offers support and binaries for OpenJDK™, Spring, and Apache Tomcat® in one simple subscription.

Learn more

Upcoming events

Check out all the upcoming events in the Spring community.

View all