The following tutorial implements a REST API server using the Rust Diesel ORM. The scenario is that of an e-commerce application where database access is managed using the Entity Framework Core. The e-commerce database (ysql_diesel) 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 application can be found in the Using ORMs with YugabyteDB repository.

Prerequisites

This tutorial assumes that you have:

  • YugabyteDB running. If you are new to YugabyteDB, follow the steps in Quick start.
  • Rust 1.31 or later.

Clone the "orm-examples" repository

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

Build the REST API server (written using Diesel and Rocket) as follows:

$ cargo build --release

If you encounter a build failure, install libpq and try again.

Configure the database

The database connection settings are managed using the DATABASE_URL in the .env file, which is in the following format:

DATABASE_URL=postgres://<username>:<password>@<host>:<port>/<database>
Property Description Default
host Database server IP address or DNS name. localhost
port Database port where it accepts YSQL connections. 5433
username Database username. yugabyte
password User password. yugabyte
database Database instance. ysql_diesel

The default values are valid for a local YugabyteDB installation. If you are using a different configuration, change these values in the URL as required.

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_diesel database using:

yugabyte=# CREATE DATABASE ysql_diesel;

Connect to the database using:

yugabyte=# \c ysql_diesel;

Start the REST API server

In the diesel directory, start REST server at port 8080.

$ ./target/release/yugadiesel

Send requests to the application

Create two 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 two 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_diesel database using the following YSQL commands:

ysql_diesel=# select * from users;
 user_id | first_name | last_name |      user_email
---------+------------+-----------+----------------------
       1 | John       | Smith     | [email protected]
     101 | Tom        | Stewart   | [email protected]
(2 rows)
ysql_diesel=# 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 two 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_diesel=#  \d
                      List of relations
 Schema |             Name              |   Type   |  Owner
--------+-------------------------------+----------+----------
 public | __diesel_schema_migrations    | table    | yugabyte
 public | order_lines                   | table    | yugabyte
 public | order_lines_order_id_seq      | sequence | yugabyte
 public | order_lines_order_line_id_seq | sequence | yugabyte
 public | order_lines_product_id_seq    | sequence | yugabyte
 public | orders                        | table    | yugabyte
 public | orders_order_id_seq           | sequence | 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
(12 rows)

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

ysql_diesel=# SELECT count(*) FROM users;
 count
-------
     2
(1 row)
ysql_diesel=# SELECT count(*) FROM products;
 count
-------
     2
(1 row)
ysql_diesel=# SELECT count(*) FROM orders;
 count
-------
     2
(1 row)
ysql_diesel=# SELECT * FROM order_lines;
 order_line_id | order_id | product_id | units
---------------+----------+------------+-------
             1 |        1 |          1 |     2
             2 |        2 |          1 |     2
             3 |        2 |          2 |     4
(3 rows)

order_lines 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_diesel 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",
      "price": 7.5
    },
    {
      "productId": 2,
      "productName": "Pencil",
      "price": 2.5
    }
  ],
  ...
}
curl http://localhost:8080/orders
{
  "content": [
    {
      "orderId": 1,
      "orderTotal": "15.00",
      "userId": 1
    },
    {
      "orderId": 2,
      "orderTotal": "25.00",
      "userId": 1
    }
  ]
}

Explore the source

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