Replies: 9 comments 16 replies
-
Hey @karatakis, awesome! I think adding authorizarion for GraphQL endpoints will be a good future work. However, it might be out-of-scope and it should be provided by the underlaying GraphQL library |
Beta Was this translation helpful? Give feedback.
-
Thank you for the long passage. Here is my feedback:
|
Beta Was this translation helpful? Give feedback.
-
I made a demo to showcase the generated code scenario https://github.com/karatakis/rust-graphql-generator The demo can do basic query To run the example: $ cargo install sea-orm-cli
$ cargo run generated
$ cp chinook.db ./generated/chinook.db
$ cd generated
$ cargo run Then go to link http://localhost:8000/ Its still WIP, that is why I have some things hard coded. I love how it works so far and I think I will stick to the code generator scenario. Feedback will be appreciated |
Beta Was this translation helpful? Give feedback.
-
I checked that and it's really impressive! Actually, such a small library can generate all these amount of code with those functionality is unimaginable. Anyway, going forward, I see lots of repetition in the generated code. #[derive(async_graphql :: InputObject, Debug)]
pub struct AlbumsAlbumIdFilter {
pub eq: Option<i32>,
pub ne: Option<i32>,
pub gt: Option<i32>,
pub gte: Option<i32>,
pub lt: Option<i32>,
pub lte: Option<i32>,
pub is_in: Option<Vec<i32>>,
pub is_not_in: Option<Vec<i32>>,
pub is_null: Option<bool>,
} We might probably want to hide these behind a derive macro instead like below to reduce the entropy. numeric_filter!(AlbumsAlbumIdFilter); Although it might be too much magic at this level of abstraction. The goal is to make the generated code concise enough to be readable but still elaborate enough to be understandable, and flexible enough to be customizable. Awesome work all in all! |
Beta Was this translation helpful? Give feedback.
-
My next milestone will be relational queries. For each entity I will utilize its foreign keys and append a getter for its related entity. Problem: Easy Solution:
Complex Solution: Resources:
|
Beta Was this translation helpful? Give feedback.
-
the generator now supports related queries but without optimization for (1+N) problem. Next steps:
|
Beta Was this translation helpful? Give feedback.
-
I gave a solution to N+1 problem Features so far:
Issues solved but not implemented:
My long term plans are:
|
Beta Was this translation helpful? Give feedback.
-
You are turning a dream that I have had for years into a beautiful reality, guys! I'm not as good at programming in Rust as you are, but I'm picky and precise when it comes to testing even in the enterprise environment. Can't wait to start testing. Queries with complex filters are a real joy. In a few days I will have time to try and would like to use async-graphql. Thank you very much! |
Beta Was this translation helpful? Give feedback.
-
Amazing guys, I'm using gqlgen (like async-graphql or juniper but in Go not in Rust) and Ent as ORM (but is more than an ORM). I'm writing to you because I just found out an excellent feaure of Ent: GraphQL Field Collection. Since you are dedicating yourself to this type of work, I thought this feature might interest you to add it among the wonderful pearls of SeaORM. Basically Ent with this feature offers the possibility to AVOID ALL THE DATALOADERs. Do you think it can be done? It would be REVOLUTIONARY! As it was with Ent. Thank you for your work. |
Beta Was this translation helpful? Give feedback.
-
Design Document
Purpose
This document's purpose is to document technical details, the system architecture and the development steps of the proposed
project.
Audience
Every developer with a good knowledge of Rust, GraphQL, SQL, software architecture and good will is encouraged to participate in the discussion.
Description
A tool that discovers the database schema and generates a GraphQL API that supports
essential CRUD operations.
Benefits
This project is a great opportunity to:
Risks
Resources
Related resources, material and projects.
Dependencies
Libraries our project will depend on:
Reference Documentation
Important documentation material:
Articles / Issues / Discussions
Related articles, issues and discussions regarding our projects:
How to create an entity where (most) fields and the type are only known at runtime? graphql-rust/juniper#957
They are discussing how to implement dynamic GraphQL schema using juniper
library
Supporting Dynamic, Programmatic Schema async-graphql/async-graphql#495
Discussion regarding dynamic GraphQL schema generation using async-graphql
library. It is impossible to use non runtime types, a workaround is to use macro
code.
http://www.petecorey.com/blog/2017/06/12/graphql-nosql-injection-through-json-types
https://hasura.io/docs/latest/graphql/core/databases/postgres/queries/query-filters.html
https://hasura.io/blog/building-a-graphql-to-sql-compiler-on-postgres-ms-sql-and-mysql
https://dgraph.io/docs/graphql/queries/search-filtering/#filter-a-query-for-a-range-of-objects-with-between
https://graphql.org/learn/queries
https://docs.fauna.com/fauna/current/api/graphql/relationships
https://www.apollographql.com/blog/graphql/filtering/how-to-search-and-filter-results-with-graphql
https://docs.fauna.com/fauna/current/api/graphql/relationships
Similar projects
https://github.com/ForetagInc/Alchemy
ArangoDB to GraphQL API generator
https://github.com/graphile/postgraphile
https://github.com/hasura/graphql-engine
System Overview
The application will be separated logically into 3 modules: database exploring, schema generation and execution engine.
Database exploring
Database exploring is responsible to explore the database schema and generate a database definition schema the next steps will depend on. An example output of this step is located here for the sample database
Schema generation
Is responsible to generate GraphQL types, enumerations, queries and mutations from the database definition schema. Enumerations will be generated whenever possible (mysql, pgsql). For every table type (Row) we will have the following generated queries: single row query, filtered by primary key, and paginated query using filters. Regarding mutations for every table we will support: single insert* , batch inserts*, single update**, batch updates** based on filters, single delete using ID and batch deletes based on filters. The juniper Registry will be used to store the generated items.
* optional create with relations
** optional update with atomic operations (ex. x = x + 1)
Execution engine
Is responsible to generate SQL queries from incoming GraphQL query/mutation requests, execute them into the database and return the appropriate response back. sea_query will be the main library used tin the execution engine. The execution engine will perform SQL queries with joins, filters, pagination and aggregator functions. In addition to queries, the engine will be able to perform SQL insert, batch inserts, update, batch updates, delete, and batch deletes.
Example
We will use the following database to demonstrate the application. Note we use only albums and artists tables with the publishedAt (date) field added to the albums table. I did some tinkering on my own on the following repo, its a WIP proof of concept!!!
We produce the database schema definition, you can find it here.
We generate the GraphQL schema types, queries and mutations.
Ways to approach project
We can approach the problem in 3 different ways:
and generate types, queries and mutations on the fly.
time and generate rust code for the types, mutations and queries.
when a user executes the tool, and writes rust code that is ready to be
compiled.
Advantages:
extension/modification
extension/modification
Disadvantages:
types), hard to allow user extension/modification
Deliverables
If we choose the runtime based project we will have to deliver:
examples, and testing
List of tasks
Future work
Beta Was this translation helpful? Give feedback.
All reactions