Skip to content

Explain non-pythonic design and structures #612

Closed
@danpalmer

Description

@danpalmer

This is quite a general thing, so I'd appreciate thoughts from the maintainers, and some ideas for solutions.

I come from a Python background, and while reading the documentation I've found that the code goes against things I would expect of Python code in various ways. While this isn't critical to being usable at a small scale, while thinking about how this will fit into our codebase, and how other developers will get up to speed on using it, I think it will hold back adoption significantly.

I'm sure there are good reasons for some of the unexpected designs, but I think it would be great to give time to this in the documentation.

Places where I think this documentation is necessary:

  • What is a promise? Promises aren't a concept in Python, and it might be assumed that async/await could be used instead. Providing a brief reason for why promises are used in Graphene and links to further documentation would be great.

  • self not being a class instance in resolver 'methods'. I don't understand the architectural reasons why this can't be the case, but in Python an instance method (like the resolver methods) is expected to take a self first argument. The documentation says that this isn't the case with Graphene (which is unexpected), but it still calls the argument self in some cases which further confuses the issue. It is mentioned that these methods act like static methods, however it's unexpected that they aren't decorated with the @staticmethod decorator.

  • Interfaces are listed in a Meta class attribute. In normal Python I would expect these to be in the inheritance tree, perhaps as an abstract base class using abc. Again I'm sure there are great reasons why this is not the case, but giving some motivation for this in the documentation would go a long way to making Graphene easier to understand.

  • Middleware is implemented object instances with a resolve method. Again I'm sure there are reasons for this, but I wonder if the class is needed, could middleware just be a function (I think this would be more Pythonic). Alternatively, middleware could be specified to Graphene as classes, not instances, and Graphene could instantiate on each request-response cycle so that the instance is able to hold data in the request lifecycle. This is how Django does it, and it can be useful with more complex middleware. Right now that is not well supported.

Graphene is powerful, and I'm confident that it will be a great way to implement GraphQL APIs in Python codebases, however right now I think it could be quite intimidating for Python developers looking at it for the first time because of how differently it appears to work. I believe most of this can be solved with documentation.

I'd appreciate your thoughts on the state of the documentation, your thoughts on the above examples that I've highlighted, and what you think the path forward is for documenting these things.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions