Skip to main content

Java Spring Boot REST Server with CockroachDB

🕓 45 minutes

What you’ll learn

How to set up your application for :

  • connecting to the CockroachDB database
  • getting data from REST API
  • providing data to REST API from the database.

In this tutorial, we will create a simple java component with Java Spring Boot scaffolder with a connection to CockroachDB database storage. We want to expose a single REST endpoint for getting the basic client data information, creating a microservice CRUD layer above the DB storage.

clientDataDB

Project source

This example project can be cloned from: http://gitlab.cloud.codenow.com/public-docs/java-spring-boot-demo/java-spring-boot-rest-server-with-cockroachdb.git

Prerequisites

Steps

Open your IDE, import the created component and start coding:

  • Add these maven dependencies to your pom.xml file:

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>2.3.3.RELEASE</version>
    </dependency>

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

    <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.4.21.Final</version>
    </dependency>

    <dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.2.11</version>
    </dependency>
  • Define jpa entity Client. This simple table will store the basic client data:

    • Generate getters and setters with your IDE
    • NOTE: if your table name is different from the model class name, you should specify the table name inside the @Table annotation.
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.Table;

    @Entity
    @Table(name = "client_data")
    public class Client {

    @Id @GeneratedValue
    private Long id;

    private String username;
    private String firstname;
    private String surname;

    //...getters + setters
    }
  • Create a new ClientRepository, which is a basic CRUD interface for Spring Boot data DB access:

    import org.example.service.model.Client;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;

    @Repository
    public interface ClientRepository extends JpaRepository<Client, Long> {
    Client getClientByUsername(String username);
    }
  • Create a new controller and put all the parts together

    import org.example.service.model.Client;
    import org.example.service.repository.ClientRepository;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;

    import java.util.List;

    @RestController("/clients")
    public class ClientController {

    private static final Logger LOG = LoggerFactory.getLogger(ClientController.class);

    @Autowired
    private ClientRepository clientRepository;

    public ClientController(ClientRepository clientRepository) {
    super();
    this.clientRepository = clientRepository;
    }

    @GetMapping
    private ResponseEntity<List<Client>> getAll() {
    List<Client> clients = clientRepository.findAll();

    if(clients.size() <= 0) {
    return new ResponseEntity<>(null, HttpStatus.NO_CONTENT);
    }

    return new ResponseEntity<>(clients, HttpStatus.OK);
    }

    @GetMapping("/{username}")
    private ResponseEntity<Client> getClientByUsername(@PathVariable String username) {
    LOG.info("Get data for username: {}", username);
    Client client = clientRepository.getClientByUsername(username);

    if(client == null) {
    return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
    }
    return new ResponseEntity<>(client, HttpStatus.OK);
    }
    }
  • Next prepare the database configuration:

  • Now change the local configuration in codenow/config/application.yaml:

    • Fill {db user} and {db password} according to your local development setup

      danger

      These settings are valid only in your local development environment to connect to your local database! Never store your credentials in the codebase! You don't have to implement your own solution for the secure storage of credentials. In CodeNOW, credentials are securely stored for each deployed service (database/message broker/...). You can find how to set up the service connection in CodeNOW in the Deployment Tutorial and in the Connecting Services Tutorial.

    • Make sure you follow yaml syntax (especially whitespaces)

    server:
    port: 8080
    spring:
    main:
    banner-mode: off
    zipkin:
    enabled: false
    datasource:
    url: jdbc:postgresql://localhost:26257/{db name}}
    username: {db user}
    password: {db password}
    driver-class-name: org.postgresql.Driver
    jpa:
    properties:
    hibernate:
    dialect: org.hibernate.dialect.PostgreSQL95Dialect
    management:
    endpoints:
    web:
    exposure:
    include: health, prometheus
  • Try to build and run the application in your IDE. After startup, you should be able to access your new controller’s swagger: http://localhost:8080/swagger/index.html

clientDataDBSwagger1

Deploy to CodeNOW

If your code works in the local development, you are ready to push your changes to GIT and try to build and deploy your new component version to the CodeNOW environment.

What’s next?

See our other developer tutorials: