LoginSignup
3
0

【Day 23】ブログ一覧を取得し、表示する - SeaORM

Last updated at Posted at 2023-12-22

はじめに

スライド24.PNG

2023年アドベントカレンダー23日目です。

本日は昨日に引き続き、「ユーザーはトップページでブログタイトルの一覧を見ることができる」を進めていきます。

image.png

昨日はDriver以外の実装をしたので、今日はDriverの実装を進めていきます。

SeaORM

SeaORMとは

SeaORMとは、RustのORMです。
最近SeaORMをよく見る気がするので、使ってみようと思います

依存関係の追加

公式の例ではこのようになっています。

Cargo.toml
sea-orm = { version = "0.12", features = [ <DATABASE_DRIVER>, <ASYNC_RUNTIME>, "macros" ] }

DBはpostgresqlを選んでいるので、<DATABASE_DRIVER>にはsqlx-postgresを選択し、
<ASYNC_RUNTIME>にはruntime-async-std-native-tlsを設定します。

Cargo.toml
sea-orm = { version = "^0.12.0", features = [ "sqlx-postgres", "runtime-async-std-native-tls", "macros", "mock" ] }

このようになりました。

Database Connection

次にDatabaseと接続します。

blog/src/driver/blog_driver.rs
#[mry::mry]
pub async fn get() -> EyreResult<BlogsJson> {
    let db_url = "postgres://blog:blog@localhost:5432/blog";
    let db: DatabaseConnection = Database::connect(db_url).await?;
}

このように設定します。
dbだけ別にしたり、db_urlを環境変数にしたりということはするべきでしょう。

Generate Entities With sea-orm-cli

まず、sea-orm-cliをインストールします。

cargo install sea-orm-cli

インストールが完了したら、エンティティを作成しましょう!

実行前にDBを起動するのを忘れないようにしましょう
Postgresqlに関してはDay 18で作成しています

sea-orm-cli generate entity -u postgres://blog:blog@localhost/blog -o ./blog/src/entity

実行すると以下のようなファイルが作成されます

blog/src/entiry
├── blog.rs
├── mod.rs
└── prelude.rs
mod.rs
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6

pub mod prelude;

pub mod blog;
prelude.rs
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6

pub use super::blog::Entity as Blog;
blog.rs
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.6

use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "blog")]
pub struct Model {
    #[sea_orm(primary_key, auto_increment = false)]
    pub id: Uuid,
    pub title: String,
    pub author: String,
    #[sea_orm(column_type = "Text")]
    pub body: String,
    pub created_at: String,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}

impl ActiveModelBehavior for ActiveModel {}

Driver実装

作成したEntityを使って、DBから、ブログデータの取得をします。

blog/src/driver/blog_driver.rs
use crate::entity::blog::Entity as BlogEntity;

#[mry::mry]
pub async fn get() -> EyreResult<BlogsJson> {
    let db_url = "postgres://blog:blog@localhost:5432/blog";
    let db: DatabaseConnection = Database::connect(db_url).await?;
    let blogs = BlogEntity::find().all(&db).await.unwrap();

    let blogs_json = BlogsJson {
        blogs: blogs
            .into_iter()
            .map(|blog| BlogJson {
                id: blog.id.to_string(),
                title: blog.title.to_string(),
                author: blog.author.to_string(),
                body: blog.body.to_string(),
                created_at: blog.created_at.to_string(),
            })
            .collect(),
    };
    Ok(blogs_json)
}

これで昨日と合わせてRest, Usecase, Gateway, Driverのすべての実装が終わりました

【Day 19】で作成したE2Eテストを流してみます

参考として、テストスペックファイルを載せておきます。

e2e/specs/blog.spec
# Blog E2E

## Get Blogs

* URL"http://localhost:3000/blogs"にGETリクエストを送る
* レスポンスステータスコードが"200"である
* レスポンス内JsonBodyの"blogs[0].id"が文字列の"123e4567-e89b-12d3-a456-426614174000"である
* レスポンス内JsonBodyの"blogs[0].title"が文字列の"カフェの隅で見つけた幸せ:私のお気に入りの隠れ家"である
* レスポンス内JsonBodyの"blogs[0].author"が文字列の"田中太郎"である
* レスポンス内JsonBodyの"blogs[0].body"が文字列の"ブログの本文"である
* レスポンス内JsonBodyの"blogs[0].createdAt"が文字列の"2023-12-09 09:00:00"である
$ gauge run specs
# Blog E2E
  ## Get Blogs   ✔ ✔ ✔ ✔ ✔ ✔ ✔

すべて通りました👍
無事DBからデータを取得し、Rest層がJSONデータを返しているようです👍

明日、明後日でアドベントカレンダーも終了を迎えます。

LifeSyncのアプリケーションとしてはトップページでブログの一覧を見せることまでしか機能の作りこみはできていませんが、残りの2日間を使ってK8s環境でWeb, Bff, API, DBのすべてが起動するようにしていこうと思います👍

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0