-
I hope this won't sound as a vague discussions. My purpose is to know how various people will handle the situation of organizing the code for larger projects where there can be 50+ query and mutations. I have prepared for such situation with minimal code but I want to continue the discussion so I and other developer can get to know the various approaches that will suit their situation accordingly. Here is how I have prepared as of now where each app(product, order, review and so on) will have their own types, query, mutation and resolvers(business logic) file which are then grouped inside graphql/types.py and is called in schema.py to bind those queries and mutations. graphql/core
this folder will contain global scalars, pagination stuffs and so on.
graphql / schema.py
from .types import RootQuery, RootMutation
class MyExtension(Extension):
def on_request_start(self):
self.execution_context.context["db"] = SessionLocal()
def on_request_end(self):
self.execution_context.context["db"].close()
@strawberry.type
class Query(RootQuery):
pass
@strawberry.type
class Mutation(RootMutation):
pass
schema = strawberry.Schema(query=Query, mutation=Mutation, extensions=[MyExtension])
graphql / types.py
import strawberry
from ..account import AccountQuery, AccountMutation
from ..product import ProductQuery, ProductMutation
from ..review import ReviewQuery, ReviewMutation
from ..checkout import CheckoutQuery, CheckoutMutation
from ..order import OrderQuery, OrderMutation
from ..shipping import ShippingQuery, ShippingMutation
@strawberry.type
class RootQuery(
AccountQuery, ProductQuery, ReviewQuery, CheckoutQuery, OrderQuery, ShippingQuery
):
pass
@strawberry.type
class RootMutation(
AccountMutation,
ProductMutation,
ReviewMutation,
CheckoutMutation,
OrderMutation,
ShippingMutation,
):
pass
graphql/product/types.py
@strawberry.type
class Product:
title: str
id: typing.Optional[strawberry.ID] = None
@strawberry.input
class CreateProductInput:
title: str
@strawberry.input
class CreateProduct:
input: CreateProductInput
graphql/product/__init__.py
from .query import ProductQuery
from .mutation import ProductMutation
graphql/product/query.py
from .types import Product
@strawberry.type
class ProductQuery:
@strawberry.field
def products(self, info) -> typing.Optional[typing.List[Product]]:
# business logic on resolvers.py as resolve_products(info)
return [Product(title="Title", id=1)]
def product(self) -> typing.Optional[Product]:
return Product(title="Title", id=1)
graphql/product/mutation.py
@strawberry.type
class ProductMutation:
@strawberry.mutation
async def create_product(self, info, input: CreateProductInput) -> Product:
# business logic on resolvers.py as resolve_create_product(info)
return Product(title="Title", id=1) Any feedback or different approaches is appreciated. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
@Tushant for mutations at least (though it would work for Query as well) I tend to use the For example I have a file from strawberry.tools import create_type
from .mutations.create_product import create_product
from .mutations.add_review import add_review
Mutation = create_type(
"Mutation",
[
create_product,
add_review,
]
) You can imagine how that might work across multiple folders which each folder exporting a list of mutations and a central file merging them all together. One benefit of this approach is that you can pre-process your list of mutations and make sure that none of the names clash (which you can't do with inheritance). Side note: don't call your api folder "graphql" because it will clash with the "graphql" library that Strawberry relies on 😛 |
Beta Was this translation helpful? Give feedback.
-
As an update to composing types, Strawberry has added from strawberry import gql
from strawberry.tools import merge_types
@gql.type
class QueryA:
...
@gql.type
class QueryB:
...
Query = merge_types("Query", (QueryA, QueryB))
schema = gql.Schema(query=Query) |
Beta Was this translation helpful? Give feedback.
-
Is there any option to prevent name clashes when merging multiple types together, e.g. by prefixing field names? For example consider
which generates a type with just a single field |
Beta Was this translation helpful? Give feedback.
@Tushant for mutations at least (though it would work for Query as well) I tend to use the
create_type
tool: https://strawberry.rocks/docs/guides/tools#create_typeFor example I have a file
api/mutation.py
which looks like this:You can imagine how that might work across multiple folders which each folder exporting a list of mutations and a central file merging them all together. One benefit of this approach is that you can pre-process your list of mutations and make sure th…