Comments (14)
I agree, it makes sense to experiment with other approaches and create a library that is Pythonic from the start, instead of the approach of copying GraphQL.js 1:1 and then putting a more Python wrapper on top. But I think GraphQL-core should stay what it is, and this should be done in other projects.
from graphql-core.
Resolvers are supposed to be staticmethods, so there is no self to pass None or any other value to.
That said, this design choice was inherited from graphql.js (where it makes sense due to JavaScript generally not using class syntax to create queries, and the problems with binding this in JS).
It makes less sense in Python, and isnβt really part of the graphql spec but this lib is attempting to be a direct port from the JavaScript so it inherited some odd semantics: static resolvers, promises, heavy use of lambdas, etc.
from graphql-core.
@KaySackey Exactly, I am considering write a wrapper for graphql-core to make it friendlier to Python.
from graphql-core.
@Cito That's the reason I wrote Pygraphy as a supplement to graphql-core-next.
from graphql-core.
Thank you for this suggestion @ethe - I think I understand your use case. However, I'm very reluctant to change anything that breaks the compatibility with the GraphQL.js by introducing different or additional behavior. Maybe some people detect that they are at root by comparing the object with None
.
My suggestion is to determine the type automatically before running the query, something like this:
root_value = get_operation_root_type(schema, parse(query).definitions[0])
And then passing it explicitly as the root_value
argument when running the query.
from graphql-core.
Passing None
to self
is not in good taste I think, cause it is conflict with common sense. But it is sensible if root_value
is used in stand alone function such as
schema = GraphQLSchema(GraphQLObjectType("Query", {"test": GraphQLField(
GraphQLString,
args={
"aStr": GraphQLArgument(GraphQLString),
"aInt": GraphQLArgument(GraphQLInt),
},
resolve=lambda source, info, **args: dumps([source, args]))}))
So I think maybe we need to treat method resolver and function resolver in different ways.
from graphql-core.
@ethe Wouldn't it work when you pass bound methods as resolvers to graphql-core?
from graphql-core.
@Cito There are not good opportunities to initialize the Query object. Neither graphene nor strawberry support that.
from graphql-core.
I think the way forward then is to discuss this as a Graphene or Strawberry issue and if it turns out it really cannot be solved without additional support of GraphQL-core, then reopen an issue here.
Note that it is already possible to use a custom ExecutionContext
class in GraphQL-core where you can overwrite the execute_operation
method as you like.
Closing this for now as currently don't think this is something that should be addressed by GraphQL-core.
from graphql-core.
I just create another library and rewrite the whole of type system design to avoid those weird behaviors: https://github.com/ethe/pygraphy, cause it is really hard to walk around. The type object should be a metaclass in a more pythonic way, and it is natural to realize the user custom type initialized from type metaclasses.
from graphql-core.
@ethe isn't that exactly what Graphene is doing?
from graphql-core.
Sorry, I do not think any library which is based on graphql-core(-next) can totally solve this issue. To those class-based model approach implementation such as Graphene and Strawberry, make type class be a python meta class is the best way to solve those weird behaviors, it is a more pythonic way. However, it can not just be inherited from graphql.js, cause Javascript have neither class nor meta class.
from graphql-core.
@Cito The root cause is, core uses object-based type declaration system(type classes are python class and user custom types are class instances), it is counterintuitive in Python. It is natural that as a higher-ranked type, type class should be metaclass, then we got all custom types becomes python class, and object just be an object in Python. Everything is perfectly matched.
from graphql-core.
Let me compare with the type declaration design between GraphQL-Core and Pygraphy.
The type class of core is just python class
class GraphQLObjectType:
pass
And user custom type is a python instance.
CustomFoo = GraphQLObjectType(
name='CustomFoo',
fields={}
)
See where the inharmony is? the CustomFoo is not a python class so it can not bind any method on it. Every solution attempts to walk around is ugly and not pythonic. Pass an unbounded method as a resolver field? No, stop doing that. Initialize the model object and pass bounded method in? Where and when can I initialize it? And If I want to keep the behavior of each request having their standalone instance, I can not see a way to realize it.
The type declaration design of Pygraphy like the below example:
class GraphQLObjectType(type):
pass
class GraphQLObject(metaclass=GraphQLObjectType):
pass
class UserCustomFoo(GraphQLObject):
pass
UserCustomFoo inherits from a common Object class which is bound to a meta class. There is also an initialization here, but it happens in class defining rather than object initializing.
Obviously, we can bind a resolver as a python method to the UserCustomFoo naturally and all things obey the intuition of Python developing.
from graphql-core.
Related Issues (20)
- subscribe breaking change in graphql version 3.3.0a3 HOT 1
- [Question] How to map operation variables to their uses? HOT 2
- Using Relays in Graphql-core raises a TypeError HOT 4
- `out_name` is not respected for input objects used as default argument value
- Segfault during schema parsing HOT 3
- Segfault during schema parsing
- `graphql.utilities.print_schema` module contents are hidden behind `utilities` package
- `deepcopy` fails if the schema has a directive with an enum argument
- Both `typing.ByteString` and `typing.Text` are deprecated and slated for removal in Python 3.14 HOT 3
- Add the ability to specify `GraphQLResolveInfo.context` type HOT 1
- I use middleware for that right now HOT 1
- construction fails for depth around > 200 / resource exhaustion? HOT 9
- Cancel resolver tasks if execution of an operation is terminated HOT 7
- Support for official @oneof directive HOT 1
- How do you run tests with an IDE? HOT 4
- Pregenerate and Caching GraphqlSchema with Pickle HOT 4
- Validation/coercion of input variables violates the GraphQL spec HOT 1
- Inquiry about the release of a stable version after 3.2.3 HOT 1
- Variable values ordering not kept during execution HOT 2
- How to pass additional information to GraphQLResolveInfo
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphql-core.