바다학 시작하기

SeaographySeaORM을 사용하여 GraphQL 리졸버를 빌드하기 위한 GraphQL 프레임워크입니다. 기존 MySQL, Postgres 및 SQLite 데이터베이스에서 바로 컴파일할 수 있는 Rust 프로젝트를 생성할 수 있는 CLI 도구와 함께 제공됩니다.

Seaography의 설계 및 구현은 당사의 release blog postdocumentation에서 찾을 수 있습니다.

SeaORM 프로젝트 확장



Seaography는 SeaORM 위에 구축되기 때문에 SeaORM 프로젝트에서 쉽게 GraphQL 서버를 구축할 수 있습니다.

Seaography 및 GraphQL 종속성을 Cargo.toml 에 추가하여 시작하십시오.

[dependencies]
sea-orm = { version = "^0.9", features = [ ... ] }
+ seaography = { version = "^0.1", features = [ "with-decimal", "with-chrono" ] }
+ async-graphql = { version = "4.0.10", features = ["decimal", "chrono", "dataloader"] }
+ async-graphql-poem = { version = "4.0.10" }


그런 다음 SeaORM 엔티티에서 몇 가지 매크로를 파생시킵니다.

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

#[derive(
    Clone,
    Debug,
    PartialEq,
    DeriveEntityModel,
+   async_graphql::SimpleObject,
+   seaography::macros::Filter,
)]
+ #[graphql(complex)]
+ #[graphql(name = "FilmActor")]
#[sea_orm(table_name = "film_actor")]
pub struct Model {
    #[sea_orm(primary_key, auto_increment = false)]
    pub actor_id: i32,
    #[sea_orm(primary_key, auto_increment = false)]
    pub film_id: i32,
    pub last_update: DateTimeUtc,
}

#[derive(
    Copy,
    Clone,
    Debug,
    EnumIter,
    DeriveRelation,
+   seaography::macros::RelationsCompact,
)]
pub enum Relation {
    #[sea_orm(
        belongs_to = "super::film::Entity",
        from = "Column::FilmId",
        to = "super::film::Column::FilmId",
        on_update = "Cascade",
        on_delete = "NoAction"
    )]
    Film,
    #[sea_orm(
        belongs_to = "super::actor::Entity",
        from = "Column::ActorId",
        to = "super::actor::Column::ActorId",
        on_update = "Cascade",
        on_delete = "NoAction"
    )]
    Actor,
}


또한 GraphQL 서버에 대해 QueryRoot를 정의해야 합니다. 이것은 GraphQL 스키마를 정의합니다.

#[derive(Debug, seaography::macros::QueryRoot)]
#[seaography(entity = "crate::entities::actor")]
#[seaography(entity = "crate::entities::film")]
#[seaography(entity = "crate::entities::film_actor")]
pub struct QueryRoot;



use sea_orm::prelude::*;

pub mod entities;
pub mod query_root;

pub use query_root::QueryRoot;

pub struct OrmDataloader {
    pub db: DatabaseConnection,
}


마지막으로 GraphQL 서버를 구동할 실행 파일을 만듭니다.

use async_graphql::{
    dataloader::DataLoader,
    http::{playground_source, GraphQLPlaygroundConfig},
    EmptyMutation, EmptySubscription, Schema,
};
use async_graphql_poem::GraphQL;
use poem::{handler, listener::TcpListener, web::Html, IntoResponse, Route, Server};
use sea_orm::Database;
use seaography_example_project::*;
// ...

#[handler]
async fn graphql_playground() -> impl IntoResponse {
    Html(playground_source(GraphQLPlaygroundConfig::new("/")))
}

#[tokio::main]
async fn main() {
    // ...

    let database = Database::connect(db_url).await.unwrap();
    let orm_dataloader: DataLoader<OrmDataloader> = DataLoader::new(
        OrmDataloader { db: database.clone() },
        tokio::spawn,
    );

    let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription)
        .data(database)
        .data(orm_dataloader)
        .finish();

    let app = Route::new()
        .at("/", get(graphql_playground)
        .post(GraphQL::new(schema)));

    Server::new(TcpListener::bind("0.0.0.0:8000"))
        .run(app)
        .await
        .unwrap();
}


데이터베이스에서 프로젝트 생성



가지고 있는 것이 데이터베이스 스키마뿐이라면 좋은 소식입니다! 한 줄의 코드를 작성하지 않고도 GraphQL 서버를 설정할 수 있습니다.

설치seaography-cli, 데이터베이스 스키마를 기반으로 전체 Rust 프로젝트와 함께 SeaORM 엔티티를 생성하는 데 도움이 됩니다.

cargo install seaography-cli


실행seaography-cli하여 GraphQL 서버용 코드를 생성합니다.

# The command take three arguments
seaography-cli <DATABASE_URL> <CRATE_NAME> <DESTINATION>

# MySQL
seaography-cli mysql://root:root@localhost/sakila seaography-mysql-example examples/mysql
# PostgreSQL
seaography-cli postgres://root:root@localhost/sakila seaography-postgres-example examples/postgres
# SQLite
seaography-cli sqlite://examples/sqlite/sakila.db seaography-sqlite-example examples/sqliteql


예제 프로젝트 확인



데이터베이스를 초기화하기 위한 SQL 스크립트와 함께 다음 예제가 있습니다.
  • MySQL
  • PostgreSQL
  • SQLite

  • 모든 예제는 실행 시 웹 기반 GraphQL 플레이그라운드를 제공하므로 GraphQL 스키마를 검사하고 쿼리를 작성할 수 있습니다. 우리는 또한 당신이 그것을 가지고 놀고 싶어 기다릴 수 없는 경우를 대비하여 demo GraphQL playground을 호스팅했습니다.

    GraphQL 서버 시작하기



    GraphQL 서버를 시작할 준비가 되었습니다! Rust 프로젝트 루트로 이동한 다음 cargo run를 실행하여 실행합니다.

    $ cargo run
    
    Playground: http://localhost:8000
    


    http://localhost:8000에서 GraphQL 플레이그라운드를 방문하십시오.



    GraphQL을 통한 쿼리 데이터



    2006년 이후에 개봉한 첫 3편의 영화를 제목의 오름차순으로 정렬하고 싶다고 가정해 보겠습니다.

    {
      film(
        pagination: { limit: 3, page: 0 }
        filters: { releaseYear: { gte: "2006" } }
        orderBy: { title: ASC }
      ) {
        data {
          filmId
          title
          description
          releaseYear
          filmActor {
            actor {
              actorId
              firstName
              lastName
            }
          }
        }
        pages
        current
      }
    }
    


    GraphQL 쿼리를 실행한 후 다음 JSON 결과를 얻었습니다.

    {
      "data": {
        "film": {
          "data": [
            {
              "filmId": 1,
              "title": "ACADEMY DINOSAUR",
              "description": "An Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies",
              "releaseYear": "2006",
              "filmActor": [
                {
                  "actor": {
                    "actorId": 1,
                    "firstName": "PENELOPE",
                    "lastName": "GUINESS"
                  }
                },
                {
                  "actor": {
                    "actorId": 10,
                    "firstName": "CHRISTIAN",
                    "lastName": "GABLE"
                  }
                },
                // ...
              ]
            },
            {
              "filmId": 2,
              "title": "ACE GOLDFINGER",
              "description": "A Astounding Epistle of a Database Administrator And a Explorer who must Find a Car in Ancient China",
              "releaseYear": "2006",
              "filmActor": [
                // ...
              ]
            },
            // ...
          ],
          "pages": 334,
          "current": 0
        }
      }
    }
    


    뒤에서 다음 SQL이 쿼리되었습니다.

    SELECT "film"."film_id",
           "film"."title",
           "film"."description",
           "film"."release_year",
           "film"."language_id",
           "film"."original_language_id",
           "film"."rental_duration",
           "film"."rental_rate",
           "film"."length",
           "film"."replacement_cost",
           "film"."rating",
           "film"."special_features",
           "film"."last_update"
    FROM "film"
    WHERE "film"."release_year" >= '2006'
    ORDER BY "film"."title" ASC
    LIMIT 3 OFFSET 0
    
    SELECT "film_actor"."actor_id", "film_actor"."film_id", "film_actor"."last_update"
    FROM "film_actor"
    WHERE "film_actor"."film_id" IN (1, 3, 2)
    
    SELECT "actor"."actor_id", "actor"."first_name", "actor"."last_name", "actor"."last_update"
    FROM "actor"
    WHERE "actor"."actor_id" IN (24, 162, 20, 160, 1, 188, 123, 30, 53, 40, 2, 64, 85, 198, 10, 19, 108, 90)
    


    내부적으로 Seaography는 N+1 문제를 해결하기 위해 중첩된 개체를 쿼리할 때 async_graphql::dataloader을 사용합니다.

    자세한 내용은 Seaography Documentation 을 확인하십시오.

    결론



    Seaography는 SeaORM 엔터티를 GraphQL 노드로 바꾸는 인체공학적 라이브러리입니다. 일련의 유틸리티를 제공하고 코드 생성기와 결합하여 GraphQL API를 쉽게 구축할 수 있습니다.

    그러나 Seaography는 아직 갓 태어난 작품입니다. 열정적인 Rust 개발자가 개발한 다른 모든 오픈 소스 프로젝트와 마찬가지로 개념이 흥미롭다면 기여할 수 있습니다. SeaQL 생태계에 추가됨에 따라 우리는 Rust가 데이터 엔지니어링을 위한 최고의 도구라는 비전에 한 걸음 더 가까워졌습니다.

    사람들



    Seaography는 다음에 의해 생성됩니다.

  • Panagiotis Karatakis - 코드 기여자의 여름; Seaography 개발자

  • Chris Tsang - 코드 멘토의 여름; SeaQL 수석 개발자

  • Billy Chan - 코드 멘토의 여름; SeaQL의 핵심 멤버
  • 좋은 웹페이지 즐겨찾기