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…

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…

This Week in Spring - September 8, 2015

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

Welcome to another installation of This Week in Spring! This week I left Tokyo, Japan, and have been in Shanghai, China, speaking to a few large-scale startups - including Ele.me, the largest food delivery service and application in a very crowded Chinese market with more than 2 million orders every day - about building cloud-native applications using Spring Boot, Spring Cloud and Cloud Foundry! Tomorrow, it's off to Oslo, Norway, for the amazing JavaZone conference. I love this conference and have, in the last two years, been unable to attend because it was concurrent with SpringOne2GX…

Spring REST Docs 1.0.0.RC1

Engineering | Andy Wilkinson | September 08, 2015 | ...

I'm delighted to announce that Spring REST Docs 1.0.0.RC1 has been released and is available from our milestone repository.

If you'd like to see some examples of what can be produced with Spring REST Docs, please take a look at the sample documentation.

What's new

Getting…

What's New In Spring Data Release Gosling?

Engineering | Christoph Strobl | September 04, 2015 | ...

Over 300 issues fixed across 12 projects makes it pretty hard to keep track on what has happened since the last release. So here's a more detailed excerpt of some of the new features we've been cooking during the last iteration.

Ad-hoc JPA fetch graphs.

Since the Dijkstra release train we have been able to refer to the named entity graph declared on the entity through the @EntityGraph annotation in JPA-backed repositories. In the example below this forces firstname and lastname to be loaded eagerly, while all others remain lazily loaded.

@Entity
@NamedEntityGraphs(
  @NamedEntityGraph(name…

React.js and Spring Data REST: Part 1 - Basic Features

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

Welcome Spring community,

This is the first of several blog entries. In this session, you will see how to get a bare-bones Spring Data REST application up and running quickly. Then you will build a simple UI on top of it using Facebook’s React.js toolset.

Step 0 - Setting up your environment

Feel free to grab the code from this repository and follow along.

If you want to do it yourself, visit http://start.spring.io and pick these items:

  • Rest Repositories
  • Thymeleaf
  • JPA
  • H2

This demo uses Java 8, Maven Project, and the latest stable release of Spring Boot. This will give you a clean, empty project. From there, you can add the various files shown explicitly in this session, and/or borrow from the repository listed above.

In the beginning…​

In the beginning there was data. And it was good. But then people wanted to access the data through various means. Over the years, people cobbled together lots of MVC controllers, many using Spring’s powerful REST support. But doing over and over cost a lot of time.

Spring Data REST addresses how simple this problem can be if some assumptions are made:

  • The developer uses a Spring Data project that supports the repository model.
  • The system uses well accepted, industry standard protocols, like HTTP verbs, standardized media types, and IANA-approved link names.

Declaring your domain

The cornerstone of any Spring Data REST-based application are the domain objects. For this session, you will build an application to track the employees for a company. Kick that off by creating a data type like this:

src/main/java/com/greglturnquist/payroll/Employee.java
@Data
@Entity
public class Employee {
private @Id @GeneratedValue Long id;
private String firstName;
private String lastName;
private String description;

private Employee() {}

public Employee(String firstName, String lastName, String description) {
	this.firstName = firstName;
	this.lastName = lastName;
	this.description = description;
}

}

  • @Entity is a JPA annotation that denotes the whole class for storage in a relational table.
  • @Id and @GeneratedValue are JPA annotation to note the primary key and that is generated automatically when needed.
  • @Data and @RequiredArgsConstructor are Project Lombok annotations to autogenerate getters, setters, constructors, toString, hash, equals, and other things. It cuts down on the boilerplate.

This entity is used to track employee information. In this case, their name and job description.

Note
Spring Data REST isn’t confined to JPA. It supports many NoSQL data stores, but you won’t be covering those here.

Defining the repository

Another key piece of a Spring Data REST application is to create a corresponding repository definition.

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

}

  • The repository extends Spring Data Commons' CrudRepository and plugs in the type of the domain object and its primary key

That is all that is needed! In fact, you don’t even have to annotate this invisible if its top-level and visible. If you use your IDE and open up CrudRepository, you’ll find a fist full of pre-built methods already defined.

Note
You can define your own repository if you wish. Spring Data REST supports that as well.

Pre-loading the demo

To work this this application, you need to pre-load it with some data like this:

src/main/java/com/greglturnquist/payroll/DatabaseLoader.java
@Component
public class DatabaseLoader implements CommandLineRunner {
private final EmployeeRepository repository;

@Autowired
public DatabaseLoader(EmployeeRepository repository) {
	this.repository = repository;
}

@Override
public void run(String... strings) throws Exception {
	this.repository.save(new Employee("Frodo", "Baggins…

This Week in Spring - September 1, 2015

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

Welcome to another installment of This Week in Spring! The Spring team is hard at work on all the latest and greatest ahead of the SpringOne2GX event in Washington DC! Time is really flying! I can't beleive what we're staring down September already! This week I'm in Tokyo, Japan, participating in the Spring User Group's huge Spring in Summer event where I gave a keynote and two talks, on Spring Boot and Spring Cloud. The one day event attracted some of the company's largest websites and was a lot of fun!

Anyway, without further ado, let's get to it!

This Week in Spring - August 25th, 2015

Engineering | Josh Long | August 25, 2015 | ...

Welcome to another installment of This Week in Spring! This week I'm in Rio de Janeiro, Brazil for the lovely QCon Rio conference, and then I'm off to Tokyo, Japan for a Spring in Summer conference for local Spring users!

The team is abuzz with excitement leading up to this year's SpringOne2GX 2016, the biggest and best SpringOne2GX, ever! This year, you're going to see us do WAY more with WAY less and get it to production, to boot! This is exciting for everyone of us and it will be for audience members, as well!

Migrating a Spring Web MVC application from JSP to AngularJS

Engineering | Michael Isvy | August 19, 2015 | ...

Note on authors

This post is a guest post by Han Lim and Tony Nguyen. Han and Tony have done a great presentation at our Singapore Spring User Group on Spring + Angular JS. This blog is based on their presentation.

Abstract

In this article, we try to describe our experiences moving from server-side rendering view technologies like JSP, Struts and Velocity to client-side rendering view technologies using AngularJS, a popular Javascript framework for modern browsers. We will talk about some of the things to look out for when you are making this change and potential pitfalls you may encounter. If…

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