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

Sweet Simplicity of a REST App With Spring Boot

DZone's Guide to

Sweet Simplicity of a REST App With Spring Boot

Did you know that you can build a fully featured REST app, right down to the database, with only three Java classes? Yeah, you can, and it's pretty sweet.

· Integration Zone
Free Resource

Modernize your application architectures with microservices and APIs with best practices from this free virtual summit series. Brought to you in partnership with CA Technologies.

You can build a fully featured REST app with only three Java classes. The ingredients list of what you need is pretty straightforward. You'll be working with the following packages:

  • Spring Boot (you probably figured that out from the title).

  • The Spring Data REST package.

  • All of the dependencies that these pull in — but you probably won't care too much about these.

That's pretty much it — aside from Java, Gradle, and your favorite IDE.

What We're Going to Build

We're going to start off with something simple. Say we need a microservice to keep track of registered users in our system. We need to be able to store user data and allow it to be retrieved, updated, and deleted. In other words, we need a typical CRUD interface.

The interface, of course, will be exposed as a REST service. In addition to the regular old GET, POST, PUT, and DELETE methods, though, we'll want to support some sort of discoverable to our API, so we'll also be exposing a HATEAOS interface to allow clients to discover and dynamically adapt to our service as we expand it in the future.

We're already talking about a fair amount of functionality here, but trust me, we won't be breaking the three class rule.

The Model

Our model starts with a simple User class:

public class User {
    private String firstName;
    private String lastName;
    private String email;

    //Getters, Setters, equals and hashCode methods removed
    ...
}

Simple enough place to start. I did remove some boilerplate code from that sample, but I literally used IntelliJ to generate it all, so it really wasn't that interesting.

The Repository

Our model, of course, is pretty much useless on its own. This is where the Spring Data project comes in. Spring Data helps make it easier to manage data. The range of functionality provided is huge, and best discovered on your own. For this tutorial, the short version is that we'll be taking advantage of Spring Data's ability to make it really easy to work with JPA objects

JPA? I've Been Duped!

Yeah, I know, I didn't mention anything about JPA earlier, but the fact of the matter is that for the very basic functionality we're talking about here, we just don't need to stress out about it too much. Here's all you really need to know:

  • JPA will be storing our Model object in a single table called Users.

  • The columns will be named the same as the field names and will be typed as varchar's.

  • You won't be writing any SQL.

  • Hibernate will be doing the actual work for us.

  • You can customize pretty much everything above if you want to.

  • Oh, and in case anyone cares, JPA stands for Java Persistence API, and you can read about it here.

Carrying On

Now that we're all more comfortable, the first thing we need to do is update our model a bit. We're going to give it a db-generated primary key, and we're going to annotate it as an Entity, so the system knows that it should care.

@Entity
public class User {
    @Id @GeneratedValue
    private long id;
    private String firstName;
    private String lastName;
    private String email;

    //Getters, Setters, equals and hashCode methods removed
    ...
}

Now that you've added a field, don't forget to regenerate your equals and hashCode object, and give it it's own getter and setter.

We're still on just a single class, of course — here comes our second. Well, nearly — it's an interface, actually:

@Repository
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
    public User findByEmail(@Param("email") String email);
}

What have we done here? We've created the interface for our repository, extending the PagingAndSortingRepository that Spring Data provides. As you can probably guess, Spring Data assumes a lot for us here since we didn't need to declare any save, update, delete, or similar methods. By extending this interface, we actually get a whole bunch of good stuff:

  • Full CRUD functionality, including the ability to load all entities, load a single entity by primary key, and save, update, and delete entities.

  • The additional ability to page and sort our result sets, because nobody wants to load our entire database all at once.

  • A standard set of query extensions. As you can see here, we have a findByEmail method that allows us to define queries in a really simple manner based on the field names on the Entity.

Main Class

Of course, we need something to run - so here is our main class. As you can see, we've annotated it with @SpringBootApplication, and our main class is calling SpringApplication.run():

@SpringBootApplication
public class Application {
    public static void main(String... args) {
        SpringApplication.run(Application.class, args);
    }
}

All we need now is a build script:

buildscript {
  ext {
    springBootVersion = '1.4.1.RELEASE'
  }
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
  }
}

apply plugin: 'java'
apply plugin: 'spring-boot'

jar {
  baseName = 'rest-in-three-classes'
  version = '0.0.1'
}

repositories {
  mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
  compile('org.springframework.boot:spring-boot-devtools')
  compile('org.springframework.boot:spring-boot-starter-data-jpa')
  compile('org.springframework.boot:spring-boot-starter-data-rest')
  compile('com.h2database:h2')

  testCompile('org.springframework.boot:spring-boot-starter-test')
}

And away we go!

Shenanigans! I Call Shenanigans!

Yes, really, that's it. Don't believe me? Build and run the thing with gradle bootRun and then open http://localhost:8080/users in your favorite browser. This is what you'll see:

{
  "_embedded": {
    "users": []
  },
  "_links": {
    "self": {
      "href": "http://localhost:8080/users"
    },
    "profile": {
      "href": "http://localhost:8080/profile/users"
    },
    "search": {
      "href": "http://localhost:8080/users/search"
    }
  },
  "page": {
    "size": 20,
    "totalElements": 0,
    "totalPages": 0,
    "number": 0
  }
}

Instant REST service! Go ahead, play around — send a POST to the same URL with Content-Type: application/json, and this JSON object to create a new user:

{
  "firstName":"Bing",
  "lastName":"Crosby",
  "email":"white@christmas.com"
}

List them, PUT them, DELETE them — it all works!

Where's Everything Else?

I know, you really want a super complicated Spring configuration — sorry, not here. You were really excited to implement that repository interface? Nope, not today. You even wanted to download and install your favorite Servlet engine, and configure it just so — sorry to disappoint!

There's no sorcery here. This is Spring Boot in action, a set of libraries that make it very easy to build small, nimble, easy to extend and configure microservices. It's no longer a hassle to setup a new project; you can literally do it in five minutes. However, before we congratulate ourselves, let's take a closer look at what's going on here.

Simplified Configuration

I've been a fan of Spring for years, when I realized I could use it to make my code easier to read, more testable, and get me the transactionality of EJB without miles and miles of boilerplate code (anyone remember EJB 2.0?). Spring's Achilles Heel has always been in the configuration - when it's working, its magic, but when it's not, it's maddening.

Spring Boot (and, in fact, Spring 4 in general) addresses this with simple and rather clever auto configuration. With Spring Boot, all you need to enable a certain feature is to include a 'starter library' on the classpath. There is a slew of these available, both from Spring and from third parties. Spring has even provided what looks like a pretty comprehensive list of both.

In our case, we've included 'spring-boot-starter-data-rest' on our classpath, which gives us a whole lot:

  • It adds the Spring Data libraries to our classpath, obviously.

  • It includes the Tomcat Servlet engine on our classpath, and embeds it into the jar file. Yes, this makes the jar file larger than it otherwise would be, but it tremendously simplifies the deployment of our app.

  • It includes a bootstrap library that ties everything together when executing the JAR file.

  • Our Repository interface has a full REST web service defined and implemented automatically, complete with paging support, and a full HATEAOS design, all based on the definition of the Repository and the Entity class. Even the findByEmail method is exposed as a search resource.

Repository Implementation

The spring-boot-starter-data-jpa library is what ties Spring Data and Hibernate together - it takes our Repository interface, and provides a default implementation, meaning that we are free to focus our JPA efforts into the mapping, and we don't need to touch the API. While this doesn't mean we can get by without understanding what's going on behind the scenes, it allows us to simply eliminate an entire class of code that tends to include a lot of boiler plate, and can be error prone.

In addition, it tremendously simplifies the configuration - simply add a JDBC driver to the classpath and the connection info in an application.properties file, and you're all set to use that database. Heck, if you include the H2 in-memory JDBC driver, as we do above, it will start and stop the database for you with no further configuration at all - sweet for testing.

JPA is not my favorite library - it gives us Annotation overload at times, it's tricky to work with complex object relationships, and it provides us with a query language that's close enough to SQL to look familiar, but different enough to not work the way I usually think it should - but with a library like Spring Data, it's hard to argue that this isn't a great option.

The End

And that's it. Really! Download the code from my GitHub repo, and please, poke around and find whatever else is interesting.

This was obviously only a taste of what you can do, but it shows off that with the current state of tools, you can motivate your team to build small, independent micro-services without a lot of overhead. This isn't all that's to it, of course — good testing practices, simple deployment mechanisms, and solid discipline are still required for working with micro-services, but the bar is being lowered every day!

Have you been using SpringBoot? If so, what's your favorite feature? If not, why not, and what frameworks are you using?

The Integration Zone is proudly sponsored by CA Technologies. Learn from expert microservices and API presentations at the Modernizing Application Architectures Virtual Summit Series.

Topics:
rest api ,spring boot ,integration ,tutorial

Published at DZone with permission of Matt Corey. See the original article here.

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}