Actix-Web + Diesel + PostgresでCRUDしてみた
TL;DR
型がほしい、PythonのTypingとかじゃなくて型がほしい。ということでActix-webに入門しています。とりあえず、Dieselを使ってCRUDしてみます。
基本的には、DieselのGetting StartをActix-webを使って再現する、ということをします。
準備
まずDieselをインストールします。今回はPostgresqlを使うので、featureはpostgresのみです。postgresのためにlibpq-devが必要なので最初に入れます。
Postgresqlを立ち上げます。今回はdocker-composeを使います。
docker-compose.yaml
環境変数として.envを作成しておきます。
プロジェクトを作ってmigrationします。
migrations/${date}_create_postsというディレクトリの中にup.sqlとdown.sqlができているはずです。up.sqlがmigration runするときに使われるやつで、down.sqlがmigration redoするときに使われるやつです。これらを以下のように書き換えます。
up.sql
down.sql
migrationします。
これでセットアップは終わりです。
Rustを書く
今回使うものを入れていきます。ORMとしてDieselを、JSONを扱うためにserde類を、エラーハンドリングにanyhowを使っています。
Cargo.tml
Hello, World
まず、Actix-WebでHello worldしておきます。
ディレクトリ構成
ディレクトリ構成は以上のものを想定しています。役割は名前のままですが、Routingのためにディレクトリを作ったくらいです。publishというところでPUTを実装します。
データベースの準備
まず、データベースに接続するための設定を書きます。あと型が長いので名前をつけておきます。
database.rs
modelを書きます。Getで返すときやPostで受け取るときにJSONにSerialize/Deserializeできる必要があります。Queryとかで使うやつにはQueryable、Postで使うやつにInsertableをつけます。
models.rs
CRUDの実装
とりあえずmod.rs類を書きます。
routes/mod.rs
routes/posts/mod.rs
あとはmain.rsに以下を追記します。
main.rs
GETとPostの実装
すべてのPostsを返します。dieselはtokioをサポートしてないらしいので、web::lockを使っています。
routes/posts/get.rs
何も入れてないため、GETしても空リストしかもらえないので、POSTも実装します。
routes/posts/post.rs
main.rsを更新します。Routingの追加とデータベースへの接続を行います。
main.rs
動かしてみます。
PUTの実装
publish状態を変更するPUTを実装します。簡単のため/posts/publish/$post_idでPublish状態になることにします。
web::Path<T>はto_ownedでTになります。
routes/posts/publish.rs
main.rsにRoutingを足したあと実行してみます。
DELETEの実装
/posts/$post_idでDELETEします。
Routingを追加して実行します。
CRUDの完成です。
終わりに
実装は以下です。もう少し機能が追加されています。