Skip to main content

Java Micronaut REST Server with CockroachDB

đź•“ 45 minutes

What you’ll learn#

How to set up your application for :

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

In this tutorial, we will create a simple java component with Java Micronaut 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-micronaut-demo/rest-server-with-cockroachdb.git

Prerequisites#

Steps#

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

  • First, add maven dependency to your pom.xml

    <dependency>    <groupId>org.postgresql</groupId>    <artifactId>postgresql</artifactId>    <version>42.2.16</version></dependency><dependency>    <groupId>javax.persistence</groupId>    <artifactId>javax.persistence-api</artifactId>    <version>2.2</version></dependency><dependency>    <groupId>io.micronaut.data</groupId>    <artifactId>micronaut-data-jdbc</artifactId>    <version>1.1.3</version></dependency><dependency>    <groupId>io.micronaut.configuration</groupId>    <artifactId>micronaut-jdbc-hikari</artifactId>    <scope>runtime</scope></dependency><dependency>    <groupId>javax.annotation</groupId>    <artifactId>javax.annotation-api</artifactId>    <version>1.3.2</version></dependency>
  • Then define the jpa entity Client. This simple table will store basic client data:

    • Generate getters and setters with your IDE
      package io.codenow.client.data.db.service.repository.entity;
      import java.time.LocalDate;
      import javax.persistence.Entity;  import javax.persistence.GeneratedValue;  import javax.persistence.Id;
      @Entity  public class Client {      @Id      @GeneratedValue      private Long id;
          private String username;      private String firstname;      private String surname;      private LocalDate birthdate;  }
  • Create a new ClientRepository, which is a basic CRUD interface for micronaut data DB access:

    package io.codenow.client.data.db.service.repository;
    import io.codenow.client.data.db.service.repository.entity.Client;import io.micronaut.data.jdbc.annotation.JdbcRepository;import io.micronaut.data.repository.CrudRepository;import io.reactivex.Maybe;
    @JdbcRepositorypublic interface ClientRepository extends CrudRepository<Client, Long> {    Maybe<Client> findByUsername(String username);}
  • Create a new controller and put all the parts together

      package io.codenow.client.data.db.service.controller;
      import javax.inject.Inject;  import javax.validation.constraints.NotNull;
      import org.example.service.repository.ClientRepository;  import org.example.service.model.Client;  import io.micronaut.http.annotation.Consumes;  import io.micronaut.http.annotation.Controller;  import io.micronaut.http.annotation.Get;  import io.micronaut.http.annotation.PathVariable;  import io.micronaut.http.annotation.Produces;  import io.micronaut.validation.Validated;  import io.reactivex.Flowable;  import io.reactivex.Maybe;
      /**   * ClientDataController.   */  @Validated  @Controller("/clients")  @Produces  @Consumes  public class ClientDataController {
          private final ClientRepository clientRepository;
          @Inject      public ClientDataController(ClientRepository clientRepository) {          this.clientRepository = clientRepository;      }
          @Get("/")      public Flowable<Client> listClients() {          return Flowable.fromIterable(clientRepository.findAll());      }
          @Get("/{username}")      public Maybe<Client> getClient(@PathVariable @NotNull String username) {          return clientRepository.findByUsername(username);      }  }
  • 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)

    datasources:  default:    url: jdbc:postgresql://localhost:5432/{db_name}    driverClassName: org.postgresql.Driver    username: {db user}    password: {db password}  dialect: POSTGRES
  • Do not forget to change the swagger.yaml. Add these lines into your src/main/resources/META-INF/swagger/swagger.yaml :

    paths:  /clients:    get:      tags:        - data      summary: Get all clients      description: Return all clients from the database      operationId: listClients      responses:        '200':          description: response          content:            application/json:              schema:                $ref: '#/components/schemas/Clients'        '400':          description: Bad request (e.g. validation)          content:            application/json:              schema:                $ref: '#/components/schemas/ErrorMessage'        '500':          description: Server error          content:            application/json:              schema:                $ref: '#/components/schemas/ErrorMessage'  /clients/{username}:    get:      tags:        - data      summary: Client by username      description: Return client by username      operationId: getClient      parameters:      - name: username        schema:          type: string        in: path        description: username      responses:        '200':          description: response          content:            application/json:              schema:                $ref: '#/components/schemas/Client'        '400':          description: Bad request (e.g. validation)          content:            application/json:              schema:                $ref: '#/components/schemas/ErrorMessage'        '500':          description: Server error          content:            application/json:              schema:                $ref: '#/components/schemas/ErrorMessage'components:  schemas:    ErrorMessage:      type: object      properties:        errorId:          type: string        traceId:          type: string        errorDetail:          type: string        errorParams:          type: array          items:            $ref: '#/components/schemas/ErrorParam'        requestMapping:          type: array          items:            type: string    ErrorParam:      type: object      required:        - key        - value      properties:        key:          type: string        value:          type: string    Clients:      type: array      items:        $ref: '#/components/schemas/Client'    Client:      required:      - id      - username      - firstname      - surname      - birthdate      type: object
  • 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

clientDataDBSwagger

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 the tutorial Micronaut REST server with Redis and Kafka.