Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
October 5, 2022 02:18 pm GMT

Getting Started with Seaography

Seaography is a GraphQL framework for building GraphQL resolvers using SeaORM. It ships with a CLI tool that can generate ready-to-compile Rust projects from existing MySQL, Postgres and SQLite databases.

The design and implementation of Seaography can be found on our release blog post and documentation.

Extending a SeaORM project

Since Seaography is built on top of SeaORM, you can easily build a GraphQL server from a SeaORM project.

Start by adding Seaography and GraphQL dependencies to your 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" }

Then, derive a few macros on the SeaORM entities.

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,}

We also need to define QueryRoot for the GraphQL server. This define the GraphQL schema.

#[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,}

Finally, create an executable to drive the GraphQL server.

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();}

Generating a project from database

If all you have is a database schema, good news! You can setup a GraphQL server without writing a single line of code.

Install seaography-cli, it helps you generate SeaORM entities along with a full Rust project based on a database schema.

cargo install seaography-cli

Run seaography-cli to generate code for the GraphQL server.

# The command take three argumentsseaography-cli <DATABASE_URL> <CRATE_NAME> <DESTINATION># MySQLseaography-cli mysql://root:root@localhost/sakila seaography-mysql-example examples/mysql# PostgreSQLseaography-cli postgres://root:root@localhost/sakila seaography-postgres-example examples/postgres# SQLiteseaography-cli sqlite://examples/sqlite/sakila.db seaography-sqlite-example examples/sqliteql

Checkout the example projects

We have the following examples for you, alongside with the SQL scripts to initialize the database.

All examples provide a web-based GraphQL playground when running, so you can inspect the GraphQL schema and make queries. We also hosted a demo GraphQL playground in case you can't wait to play with it.

Starting the GraphQL Server

Your GraphQL server is ready to launch! Go to the Rust project root then execute cargo run to spin it up.

$ cargo runPlayground: http://localhost:8000

Visit the GraphQL playground at http://localhost:8000

GraphQL Playground

Query Data via GraphQL

Let say we want to get the first 3 films released on or after year 2006 sorted in ascending order of its title.

{  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  }}

We got the following JSON result after running the GraphQL query.

{  "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    }  }}

Behind the scene, the following SQL were queried:

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" ASCLIMIT 3 OFFSET 0SELECT "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)

Under the hood, Seaography uses async_graphql::dataloader in querying nested objects to tackle the N+1 problem.

To learn more, checkout the Seaography Documentation.

Conclusion

Seaography is an ergonomic library that turns SeaORM entities into GraphQL nodes. It provides a set of utilities and combined with a code generator makes GraphQL API building a breeze.

However, Seaography is still a new-born. Like all other open-source projects developed by passionate Rust developers, you can contribute to it if you also find the concept interesting. With its addition to the SeaQL ecosystem, we are one step closer to the vision of Rust being the best tool for data engineering.

People

Seaography is created by:


Original Link: https://dev.to/seaql/getting-started-with-seaography-1elk

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To