Graphene: Advantages of `graphene` in comparison to `graphql-core`?

Created on 12 Jun 2018  路  3Comments  路  Source: graphql-python/graphene

Dear Colleagues,

we are using graphene-django for some time already. Now I came to the question why do we use graphene but not graphql-core? As far as I see, if we switch to graphql-core our code will be much closed to the original GraphQL library and tooling. We will probably have a schema in a separate file and resolvers implemented in different Python modules. It looks quite nice to me. Another advantage is that we do not have to learn one more API (I mean, graphene API).

Actually, I suppose there are advantages of using Graphene instead of graphql-core. Can you please share your thoughts on that?

question

Most helpful comment

My personal 2cts: graphene is pythonic, keeps your schema in sync with models, provides resolvers and filtering out of the box. graphql-core does none of that.

As you probably already know, graphene is a framework to make building graphql-core schemas easier. You can of course build your own schema by hand instead of using graphene-django. This means a lot more work depending on how many models you have. And when those models change, you'll need to make sure to also change the graphql schema, and the resolvers, etc.

With graphene, and in your case, graphene-django. Your graphql schema is generated for you from your django models.

From the graphene-django docs, here is a simple Django model:

from django.db import models

class UserModel(models.Model):
    name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

To create a GraphQL schema for it you simply have to write the following easy to read Python class:

from graphene_django import DjangoObjectType
import graphene

class User(DjangoObjectType):
    class Meta:
        model = UserModel

Now you already have quite a lot, you have the documented model in graphiql, you get a default resolver, you can add filters quite easily, etc.

Now you could instead do this directly with graphql-core:

userType = GraphQLObjectType(
    'User',
    description='A User',
    fields=lambda: {
        'id': GraphQLField(
            GraphQLNonNull(GraphQLString),
            description='The id of the user.',
        ),
        'name': GraphQLField(
            GraphQLString,
            description='The name of the user.',
        ),
        'last_name': GraphQLField(
            GraphQLList(characterInterface),
            description='The last name of the user.',
            resolver=lambda user, info, **args: getUser(user),
        )
    }
)

It's a matter of opinion, but to my Python eyes, that is quite an eyesore, and will be hard to keep in sync with the model classes as your project grows.

And as you said, you'll then need to implement resolvers, and filtering, etc. All code you get for free with graphene-django

All 3 comments

My personal 2cts: graphene is pythonic, keeps your schema in sync with models, provides resolvers and filtering out of the box. graphql-core does none of that.

As you probably already know, graphene is a framework to make building graphql-core schemas easier. You can of course build your own schema by hand instead of using graphene-django. This means a lot more work depending on how many models you have. And when those models change, you'll need to make sure to also change the graphql schema, and the resolvers, etc.

With graphene, and in your case, graphene-django. Your graphql schema is generated for you from your django models.

From the graphene-django docs, here is a simple Django model:

from django.db import models

class UserModel(models.Model):
    name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

To create a GraphQL schema for it you simply have to write the following easy to read Python class:

from graphene_django import DjangoObjectType
import graphene

class User(DjangoObjectType):
    class Meta:
        model = UserModel

Now you already have quite a lot, you have the documented model in graphiql, you get a default resolver, you can add filters quite easily, etc.

Now you could instead do this directly with graphql-core:

userType = GraphQLObjectType(
    'User',
    description='A User',
    fields=lambda: {
        'id': GraphQLField(
            GraphQLNonNull(GraphQLString),
            description='The id of the user.',
        ),
        'name': GraphQLField(
            GraphQLString,
            description='The name of the user.',
        ),
        'last_name': GraphQLField(
            GraphQLList(characterInterface),
            description='The last name of the user.',
            resolver=lambda user, info, **args: getUser(user),
        )
    }
)

It's a matter of opinion, but to my Python eyes, that is quite an eyesore, and will be hard to keep in sync with the model classes as your project grows.

And as you said, you'll then need to implement resolvers, and filtering, etc. All code you get for free with graphene-django

Dear @yfilali , thank you for your thoughtful response.

Indeed, using graphene-django it is really easy to expose a Django model to the GraphQL API and keep them in sync.

The reason I asked the question is because we have already implemented quite a big GraphQL schema on Graphene and only a small part of GraphQL types we have are created with graphene-django. It does work quite well, but it is hard to capture the schema reading these dozens of Python classes. That lead me to the thought that it would be nice to split the GraphQL schema declaration from the resolvers implementation. I am still not sure, but I see having schema statically declared in the language-agnostic manner is quite an interesting option.

In other words, I am still not sure that combining schema definition and schema implementation (implementation of the resolvers hierarchy) is a good approach for writing GraphQL API.

I would love to hear other opinions.

@prokher Tidying up the backlog - I don't think this requires any more info and is not a bug/other request. Please let me know if otherwise.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mraak picture mraak  路  3Comments

tricoder42 picture tricoder42  路  4Comments

dfee picture dfee  路  4Comments

ghoshabhi picture ghoshabhi  路  3Comments

mingzhou picture mingzhou  路  3Comments