Rust ORM example application
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 source for the application can be found in the Using ORMs with YugabyteDB repository.
Prerequisites
This tutorial assumes that you have:
- YugabyteDB up and running. Download and install YugabyteDB by following 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.
Set up the database connection
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" : "jsmith@example.com" }' \
-v -X POST -H 'Content-Type:application/json' http://localhost:8080/users
$ curl --data '{ "firstName" : "Tom", "lastName" : "Stewart", "email" : "tstewart@example.com" }' \
-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 | jsmith@example.com
101 | Tom | Stewart | tstewart@example.com
(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": "jsmith@example.com"
},
{
"userId": 101,
"firstName": "Tom",
"lastName": "Stewart",
"email": "tstewart@example.com"
}
],
...
}
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
}
]
}