The following tutorial implements a REST API server using the Java Ebean ORM. The scenario is that of an e-commerce application where database access is managed using the Play framework; Play uses Akka internally and exposes Akka Streams and actors in Websockets and other streaming HTTP responses. It includes the following tables:

  • users — the users of the e-commerce site
  • products — the products being sold
  • orders — the orders placed by the users
  • orderline — each line item of an order

The source for the above application can be found in the Using ORMs with YugabyteDB repository.

Prerequisites

This tutorial assumes that you have:

  • YugabyteDB up and running. If you are new to YugabyteDB, follow the steps in Quick start to have YugabyteDB up and running in minutes.
  • Java Development Kit (JDK) 1.8 is installed. JDK installers for Linux and macOS can be downloaded from OpenJDK, AdoptOpenJDK, or Azul Systems. Homebrew users on macOS can install using brew install AdoptOpenJDK/openjdk/adoptopenjdk8.
  • sbt is installed.

Clone the "orm-examples" repository

$ git clone https://github.com/YugabyteDB-Samples/orm-examples.git && cd orm-examples/java/ebean

Database configuration

  • Modify the database configuration section of the conf/application.conf file to include the YugabyteDB JDBC driver settings as follows:

    #Default database configuration using PostgreSQL database engine
    default.username=yugabyte
    default.password=""
    default.driver=com.yugabyte.Driver
    default.url="jdbc:yugabytedb://127.0.0.1:5433/ysql_ebean?load-balance=true"
    
  • Add a dependency in build.sbt for the YugabyteDB JDBC driver.

    libraryDependencies += "com.yugabyte" % "jdbc-yugabytedb" % "42.3.0"
    
  • From your local YugabyteDB installation directory, connect to the YSQL shell using:

    $ ./bin/ysqlsh
    
    ysqlsh (11.2)
    Type "help" for help.
    
    yugabyte=#
    
  • Create the ysql_ebean database using:

    yugabyte=# CREATE DATABASE ysql_ebean;
    
  • Connect to the database using:

    yugabyte=# \c ysql_ebean;
    

Build the application

Create a build.properties file under the project directory and add the sbt version.

sbt.version=1.2.8

Build the REST API server from the ebean directory using:

$ sbt compile

Note

  • Some sub-versions of JDK 1.8 require the nashorn package. If you get a compile error due to a missing jdk.nashorn package, add the dependency to the build.sbt file.

    libraryDependencies += "com.xenoamess" % "nashorn" % "jdk8u265-b01-x3"
    
  • To change the default port (8080) for the REST API Server, set the PlayKeys.playDefaultPort value in the build.sbt file.

Run the application

Run the application from the ebean directory using:

$ sbt run

Send requests to the application

Create 2 users.

$ curl --data '{ "firstName" : "John", "lastName" : "Smith", "email" : "[email protected]" }' \
   -v -X POST -H 'Content-Type:application/json' http://localhost:8080/users
$ curl --data '{ "firstName" : "Tom", "lastName" : "Stewart", "email" : "[email protected]" }' \
   -v -X POST -H 'Content-Type:application/json' http://localhost:8080/users

Create 2 products.

$ curl \
  --data '{ "productName": "Notebook", "description": "200 page notebook", "price": 7.50 }' \
  -v -X POST -H 'Content-Type:application/json' http://localhost:8080/products
$ curl \
  --data '{ "productName": "Pencil", "description": "Mechanical pencil", "price": 2.50 }' \
  -v -X POST -H 'Content-Type:application/json' http://localhost:8080/products

In your YSQL shell, verify the userId and productId from the ysql_ebean database using the following YSQL commands.

ysql_ebean=# select * from users;
 user_id | first_name | last_name |      user_email
---------+------------+-----------+----------------------
       1 | John       | Smith     | [email protected]
     101 | Tom        | Stewart   | [email protected]
(2 rows)
ysql_ebean=# select * from products;
 product_id |    description    | price | product_name
------------+-------------------+-------+--------------
          1 | 200 page notebook |  7.50 | Notebook
          2 | Mechanical pencil |  2.50 | Pencil
(2 rows)

Create 2 orders using the userId for John.

$ curl \
  --data '{ "userId": "1", "products": [ { "productId": 1, "units": 2 } ] }' \
  -v -X POST -H 'Content-Type:application/json' http://localhost:8080/orders
$ curl \
  --data '{ "userId": "1", "products": [ { "productId": 1, "units": 2 }, { "productId": 2, "units": 4 } ] }' \
  -v -X POST -H 'Content-Type:application/json' http://localhost:8080/orders

Query results

Using the YSQL shell

In your YSQL shell, list the tables created by the application.

ysql_ebean=#  \d
List of relations
 Schema |          Name           |   Type   |  Owner
--------+-------------------------+----------+----------
 public | orderline               | table    | yugabyte
 public | orders                  | table    | yugabyte
 public | orders_user_id_seq      | sequence | yugabyte
 public | products                | table    | yugabyte
 public | products_product_id_seq | sequence | yugabyte
 public | users                   | table    | yugabyte
 public | users_user_id_seq       | sequence | yugabyte
(7 rows)

Note the 4 tables and 3 sequences in the list above.

ysql_ebean=# SELECT count(*) FROM users;
 count
-------
     2
(1 row)
ysql_ebean=# SELECT count(*) FROM products;
 count
-------
     2
(1 row)
ysql_ebean=# SELECT count(*) FROM orders;
 count
-------
     2
(1 row)
ysql_ebean=# SELECT * FROM orderline;
 order_id                             | product_id | units
--------------------------------------+------------+-------
 45659918-bbfd-4a75-a202-6feff13e186b |          1 |     2
 f19b64ec-359a-47c2-9014-3c324510c52c |          1 |     2
 f19b64ec-359a-47c2-9014-3c324510c52c |          2 |     4
(3 rows)

orderline is a child table of the parent orders table, and is connected using a foreign key constraint. The users table is connected with orders using a foreign key constraint so that no order can be placed with an invalid user, and that user has to be present in the users table.

Using the REST API

To use the REST API server to verify that the users, products, and orders were created in the ysql_ebean database, enter the following commands. The results are output in JSON format.

$ curl http://localhost:8080/users
{
  "content": [
    {
      "userId": 1,
      "firstName": "John",
      "lastName": "Smith",
      "email": "[email protected]"
    },
    {
      "userId": 101,
      "firstName": "Tom",
      "lastName": "Stewart",
      "email": "[email protected]"
    }
  ],
  ...
}
$ curl http://localhost:8080/products
{
  "content": [
    {
      "productId": 1,
      "productName": "Notebook",
      "description": "200 page notebook",
      "price": 7.5
    },
    {
      "productId": 2,
      "productName": "Pencil",
      "description": "Mechanical pencil",
      "price": 2.5
    }
  ],
  ...
}
$ curl http://localhost:8080/orders
{
  "content": [
    {
      "orderTime": "2019-05-10T04:26:54.590+0000",
      "orderId": "999ae272-f2f4-46a1-bede-5ab765bb27fe",
      "orderOwner": {
        "userId": 1,
        "firstName": "John",
        "lastName": "Smith",
        "email": "[email protected]"
      },
      "userId": null,
      "orderTotal": 25.0,
      "products": null
    },
    {
      "orderTime": "2019-05-10T04:26:48.074+0000",
      "orderId": "1598c8d4-1857-4725-a9ab-14deb089ab4e",
      "orderOwner": {
        "userId": 1,
        "firstName": "John",
        "lastName": "Smith",
        "email": "[email protected]"
      },
      "userId": null,
      "orderTotal": 15.0,
      "products": null
    }
  ],
  ...
}

Explore the source

The application source is available in the orm-examples repository.