Async-graphql: RFC: Major redesigns

Created on 9 Sep 2020  路  5Comments  路  Source: async-graphql/async-graphql

First of all, master is currently breaking from 0.18, so hold off on publishing a new version until this issue is resolved.

async-graphql, as it is, has a bit of a confusing API. I propose a major overhaul of many parts to it, which I think will simplify things.

First of all, we can make a fully public Query type. It should look something like this:

pub struct Query {
    pub source: String,
    pub operation_name: Option<String>,
    pub variables: Variables,
    pub ctx_data: Data,
}

It should have many helper functions, similar to the QueryBuilder today. I'm not sure about whether to add extensions to the query struct - is it necessary, since extensions can be added to the schema also?

Then, Schema can be simplified to just two main methods:

async fn execute_query(&self, query: Query) -> QueryResponse;
async fn execute_query_stream(&self, query: Query) -> impl Stream<Item = QueryResponse>;

The Result<QueryResponse> can be replaced with adding an errors field to the QueryResponse; this will make more sense to people who are used to GraphQL as from the spec:

If the operation encountered any errors, the response map must contain an entry with key errors.

If we then allow the QueryResponse to be serialized we can ditch the GQLResponse entirely. Similarly, allowing Query to be deserialized allows us to ditch GQLRequest

Calling execute_query_stream on a query or mutation will just send one result, and calling execute_query on a subscription will panic.

Now that Schema has been reduced to a GraphQL-only API instead of handling lots of things including the transport, we could remove the ConnectionTransport trait altogether since it's handled at a higher level.

We can then feature-gate (or maybe move into a separate crate) the WebSocket implementation. Since it's no longer restricted by the ConnectionTransport trait it can have any API that is appropriate for it, I'm thinking that it could just wrap a Schema and AsyncRead + AsyncWrite.

Handling Multipart can be as simple as having a function:

pub async fn receive_multipart(multipart: impl AsyncRead) -> Query;

And also:

pub async fn receive_request(content_type: Option<impl AsRef<str>>, body: impl AsyncRead) -> Query;

Which is the same code as impl IntoQueryBuilder for (Option<CT>, Body) we had before.

Most helpful comment

I think this suggestion is very good, but since Async-graphql has been used by many projects(https://github.com/timberio/vector), I hope to create a new 2.0 branch and make changes based on that branch. At this stage, I don't want a lot of breaking changes in the 1.x version. 馃檪

All 5 comments

I think this suggestion is very good, but since Async-graphql has been used by many projects(https://github.com/timberio/vector), I hope to create a new 2.0 branch and make changes based on that branch. At this stage, I don't want a lot of breaking changes in the 1.x version. 馃檪

I am trying to refactor and when I am almost done, I will submit a PR.

I don't know whether we should have the GQL prefix, it feels like duplication from the crate name; async_graphql::GQLQuery has GQL twice. It makes more sense for users to use async_graphql as gql; gql::Query or use async_graphql::Query as GQLQuery if they want that.

I don't know whether we should have the GQL prefix, it feels like duplication from the crate name; async_graphql::GQLQuery has GQL twice. It makes more sense for users to use async_graphql as gql; gql::Query or use async_graphql::Query as GQLQuery if they want that.

Yes, I don't like the name GQLQuery, but if it is named Query, there will be a lot of conflicts. 馃槀
Maybe we can think of a better name?

Maybe Request would work. It would also be symmetric with Response.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Weasy666 picture Weasy666  路  4Comments

danielSanchezQ picture danielSanchezQ  路  4Comments

elertan picture elertan  路  5Comments

Weasy666 picture Weasy666  路  4Comments

dhendrie91 picture dhendrie91  路  3Comments