Description
Describe the Bug
According to the Strawberry documentation, a valid approach to having separate "public" and "internal" GraphQL APIs is to create two schemas.
However, if a type is shared between the two schemas that uses strawberry.relay.node
, the schema generation fails due to this line:
strawberry/strawberry/relay/fields.py
Line 58 in de07ab6
More technically, it appears that Strawberry field extensions are applied to fields each time a schema is created (instead of just once). This means that unless a field extension is written to be idempotent, unexpected behavior can occur when the same type is used in multiple schemas. See the following two failing unit tests for a minimal reproducible example: 93d627f.
At a higher level, it seems a bit scary to me that there is some level of cross-contamination between the two schemas. I would have expected that if I create a new schema, it should be completely independent of any other schemas. Is having two schemas that share the same type(s) valid in Strawberry?
Related Issues
System Information
- Operating system: MacOS
- Strawberry version: 0.262.5
- Strawberry Django version: 0.57.1
Additional Context
I stumbled across this when attempting to split my Strawberry Django GraphQL API into two schemas, one for public access and one for internal access. When I create the second schema, it crashes with the following traceback:
Traceback (most recent call last):
File "<redacted>/.venv/lib/python3.11/site-packages/graphql/type/definition.py", line 816, in fields
fields = resolve_thunk(self._fields)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<redacted>/.venv/lib/python3.11/site-packages/graphql/type/definition.py", line 300, in resolve_thunk
return thunk() if callable(thunk) else thunk
^^^^^^^
File "<redacted>/.venv/lib/python3.11/site-packages/strawberry/schema/schema_converter.py", line 637, in <lambda>
fields=lambda: self.get_graphql_fields(object_type),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<redacted>/.venv/lib/python3.11/site-packages/strawberry/schema/schema_converter.py", line 441, in get_graphql_fields
return _get_thunk_mapping(
^^^^^^^^^^^^^^^^^^^
File "<redacted>/.venv/lib/python3.11/site-packages/strawberry/schema/schema_converter.py", line 138, in _get_thunk_mapping
thunk_mapping[name_converter(field)] = field_converter(
^^^^^^^^^^^^^^^^
File "<redacted>/.venv/lib/python3.11/site-packages/strawberry/schema/schema_converter.py", line 379, in from_field
resolver = self.from_resolver(field)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "<redacted>/.venv/lib/python3.11/site-packages/strawberry/schema/schema_converter.py", line 736, in from_resolver
_get_result_with_extensions = wrap_field_extensions()
^^^^^^^^^^^^^^^^^^^^^^^
File "<redacted>/.venv/lib/python3.11/site-packages/strawberry/schema/schema_converter.py", line 687, in wrap_field_extensions
extension.apply(field)
File "<redacted>/.venv/lib/python3.11/site-packages/strawberry/relay/fields.py", line 58, in apply
assert field.base_resolver is None
^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError
I wasn't sure whether to raise this issue here or in the Strawberry Django repository, but settled with here for now.