1. What You Will Learn

  • How to use repositories for data access

  • How to expose a REST API on top of those repositories

  • How to use an embedded database for development

  • How to use a production ready database in production

  • How to gain access to the command line arguments and run specific code once

  • How to control log levels

2. Exercises

2.1. Add an Embedded Database

Review the following file: hello-spring-boot-rest/pom.xml. By adding the H2 dependency, we have added embedded database support for the hello-spring-boot-rest application. This helps us get started quickly in development, as we don’t have to provision a database.

<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
  <scope>runtime</scope>
</dependency>

2.2. Persistence With Spring Data JPA

In the same pom.xml file, you’ll notice the spring-boot-starter-data-jpa dependency, which provides Spring Data JPA support for the hello-spring-boot-rest application.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

Implementing a data access layer of an application has been cumbersome for quite a while. Too much boilerplate code has to be written to execute simple queries as well as perform pagination, and auditing. Spring Data JPA aims to significantly reduce the effort required to implement data access. As a developer you write your repository interfaces, including custom finder methods, and Spring provides the implementation automatically.

  1. Review the following file: hello-spring-boot-rest/src/main/java/io/pivotal/hello/Greeting.java. This is a typical JPA domain entity. This class represents one row in our greeting table.

    package io.pivotal.hello;
    
    import javax.persistence.Entity;
    import javax.persistence.Id;
    
    @Entity
    public class Greeting {
    
      @Id
      private Long id;
    
      private String text;
    
      public Greeting() { }
    
      public Greeting(Long id, String text) {
        this.id = id;
        this.text = text;
      }
    
      public Long getId() {
        return id;
      }
    
      public String getText() {
        return text;
      }
    
      @Override
      public String toString() {
        return "Greeting [id=" + id + ", text=" + text + "]";
      }
    
    }
  2. Review the file GreetingRepository.java. This repository interface provides CRUD operations against the greeting table. All without the developer having to write an implementation!

    package io.pivotal.hello;
    
    import org.springframework.data.jpa.repository.JpaRepository;
    
    public interface GreetingRepository extends JpaRepository<Greeting, Long> {
    
    }
  3. Review the file: hello-spring-boot-rest/src/main/resources/application.yml. The spring.jpa.hibernate.ddl-auto setting controls how/if DDL changes are made. In this case, our application will update the schema on startup if necessary. Read more on database initialization here.

    logging:
      level:
        io:
          pivotal: DEBUG
    spring:
      jpa:
        hibernate:
          ddl-auto: update

2.3. Add a Restful API with Spring Data Rest

Note that the project’s pom.xml file also includes the spring-boot-starter-data-rest dependency, which adds REST support for our JPA repositories in the hello-spring-boot-rest application.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>

The goal of the Spring Data REST project is to provide a solid foundation on which to expose CRUD operations to your repositories using plain HTTP REST semantics. Read more on Spring Data REST here.

For the GreetingRepository, Spring Data REST exposes a collection resource at /greetings. The path is derived from the uncapitalized, pluralized, simple class name of the domain class being managed. It also exposes an item resource for each of the items managed by the repository under the URI template /greetings/{id}.

We will explore the REST API, once we populate the database.

2.4. How to Run Code on Startup

In many cases, you need to run some code on startup. Spring Boot allows you capture the command line arguments and run code just as if you had implemented public static void main(String[] args) by implementing a CommandLineRunner bean.

CommandLineRunner is a core feature to Spring Boot so there are no dependencies that need to be explicitly added.

  1. Review the following file: hello-spring-boot-rest/src/main/java/io/pivotal/hello/HelloSpringBootApplication.java.

package io.pivotal.hello;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class HelloSpringBootApplication {

  private final Logger logger = LoggerFactory.getLogger(HelloSpringBootApplication.class);

  public static void main(String[] args) {
    SpringApplication.run(HelloSpringBootApplication.class, args);
  }

  @Bean
  CommandLineRunner loadDatabase(GreetingRepository repository) {
    return args -> {
      logger.debug("loading database..");
      repository.save(new Greeting(1L, "Hello"));
      repository.save(new Greeting(2L, "Hola"));
      repository.save(new Greeting(3L, "Ohai"));
      logger.debug("record count: {}", repository.count());
      repository.findAll().forEach(x -> logger.debug(x.toString()));
    };
  }

}

In this case, we are using a CommandLineRunner to populate the database with our GreetingRepository.

2.5. Turn Up Logging

To view the debug statements in the class we can turn up logging.

  1. Review the following file: hello-spring-boot-rest/src/main/resources/application.yml.

logging:
  level:
    io:
      pivotal: DEBUG

Log levels can be ERROR, WARN, INFO, DEBUG or TRACE.

Simply specify the package/class in the logging.level key and set the desired level.

In this case, we have turned on DEBUG logging for everything in the io.pivotal package.

2.6. Run hello-spring-boot-rest

  1. Open a terminal window.

    $ cd hello-spring-boot-rest
    $ mvn spring-boot:run
  2. View the logs in the terminal output. See the database being populated.

    2015-10-06 13:42:27.350 DEBUG 65573 --- [lication.main()] i.p.hello.HelloSpringBootApplication     : loading database..
    2015-10-06 13:42:27.527 DEBUG 65573 --- [lication.main()] i.p.hello.HelloSpringBootApplication     : record count: 3
    2015-10-06 13:42:27.564 DEBUG 65573 --- [lication.main()] i.p.hello.HelloSpringBootApplication     : Greeting [id=1, text=Hello]
    2015-10-06 13:42:27.564 DEBUG 65573 --- [lication.main()] i.p.hello.HelloSpringBootApplication     : Greeting [id=2, text=Hola]
    2015-10-06 13:42:27.564 DEBUG 65573 --- [lication.main()] i.p.hello.HelloSpringBootApplication     : Greeting [id=3, text=Ohai]
  3. Browse to http://localhost:8080/greetings

    greetings

    Notice that not just data is returned but links on how to navigate the API. This is provided by Spring HATEOAS as opposed to establishing a contract up front or use of documentation. Read more on HATEOAS.

  4. Experiment with paging and sorting

  5. Stop the hello-spring-boot-rest application.

What Just Happened?

When running locally, Spring Boot will use the embedded database (h2) and create the DataSource (how to connect to the database) for you.

Congratulations! You’ve completed this lab. In the next lab we’re going to discuss how to deploy this application to cloud foundry.