1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
|
---
title: Federation
---
# Federation
Strawberry Django works seamlessly with
[Strawberry's Federation support](https://strawberry.rocks/docs/guides/federation).
You can use either Strawberry's federation decorators directly or the Django-specific
`strawberry_django.federation` module which provides auto-generated `resolve_reference`
methods.
## Using `strawberry_django.federation` (Recommended)
The `strawberry_django.federation` module provides Django-aware federation decorators
that automatically generate `resolve_reference` methods for your entity types:
```python
import strawberry
import strawberry_django
from strawberry.federation import Schema as FederationSchema
from . import models
@strawberry_django.federation.type(models.Product, keys=["upc"])
class Product:
upc: strawberry.auto
name: strawberry.auto
price: strawberry.auto
# resolve_reference is automatically generated!
@strawberry_django.federation.type(models.Review, keys=["id"])
class Review:
id: strawberry.auto
body: strawberry.auto
product: Product
@strawberry.type
class Query:
@strawberry_django.field
def products(self) -> list[Product]:
return models.Product.objects.all()
schema = FederationSchema(query=Query)
```
### Federation Parameters
The `@strawberry_django.federation.type` decorator accepts all standard
`@strawberry_django.type` parameters plus federation-specific ones:
| Parameter | Type | Description |
| ----------------- | ------------------ | ------------------------------------------------------------------------------------ |
| `keys` | `list[str \| Key]` | Key fields for entity resolution (e.g., `["id"]` or `["sku package"]` for composite) |
| `extend` | `bool` | Whether this type extends a type from another subgraph |
| `shareable` | `bool` | Whether this type can be resolved by multiple subgraphs |
| `inaccessible` | `bool` | Whether this type is hidden from the public API |
| `authenticated` | `bool` | Whether this type requires authentication |
| `policy` | `list[list[str]]` | Access policy for this type |
| `requires_scopes` | `list[list[str]]` | Required OAuth scopes for this type |
| `tags` | `list[str]` | Metadata tags for this type |
### Multiple Keys
You can define multiple key fields. Each string in the list creates a separate `@key`
directive — the entity can be resolved by **either** key independently:
```python
@strawberry_django.federation.type(models.Product, keys=["id", "upc"])
class Product:
id: strawberry.auto
upc: strawberry.auto
name: strawberry.auto
```
### Composite Keys
For composite keys (multiple fields that together form a key), use a space-separated
string:
```python
@strawberry_django.federation.type(models.ProductVariant, keys=["sku package"])
class ProductVariant:
sku: strawberry.auto
package: strawberry.auto
price: strawberry.auto
```
### Custom `resolve_reference`
If you need custom logic, you can still define your own `resolve_reference`:
```python
from strawberry.types.info import Info
@strawberry_django.federation.type(models.Product, keys=["upc"])
class Product:
upc: strawberry.auto
name: strawberry.auto
@classmethod
def resolve_reference(cls, upc: str, info: Info) -> "Product":
# Custom implementation with select_related
return models.Product.objects.select_related("category").get(upc=upc)
```
### Federation Fields
Use `strawberry_django.federation.field` for federation-specific field directives:
```python
@strawberry_django.federation.type(models.Product, keys=["id"])
class Product:
id: strawberry.auto
name: strawberry.auto = strawberry_django.federation.field(external=True)
price: strawberry.auto = strawberry_django.federation.field(shareable=True)
display_name: str = strawberry_django.federation.field(
requires=["name"],
resolver=lambda self: f"Product: {self.name}",
)
```
Field parameters:
| Parameter | Type | Description |
| ----------------- | ----------------- | ------------------------------------------------ |
| `authenticated` | `bool` | Whether this field requires authentication |
| `external` | `bool` | Field is defined in another subgraph |
| `requires` | `list[str]` | Fields required from other subgraphs |
| `provides` | `list[str]` | Fields this resolver provides to other subgraphs |
| `override` | `str` | Override field from another subgraph |
| `policy` | `list[list[str]]` | Access policy for this field |
| `requires_scopes` | `list[list[str]]` | Required OAuth scopes for this field |
| `shareable` | `bool` | Field can be resolved by multiple subgraphs |
| `tags` | `list[str]` | Metadata tags for this field |
| `inaccessible` | `bool` | Field is hidden from the public API |
### Interfaces
Federation interfaces are also supported:
```python
@strawberry_django.federation.interface(models.Product, keys=["id"])
class ProductInterface:
id: strawberry.auto
name: strawberry.auto
```
## Using Strawberry's Federation Directly
You can also use Strawberry's federation decorators alongside `strawberry_django`:
```python
import strawberry
import strawberry_django
from strawberry.federation.schema_directives import Key
from . import models
@strawberry_django.type(models.Product, directives=[Key(fields="upc")])
class Product:
upc: strawberry.auto
name: strawberry.auto
price: strawberry.auto
@classmethod
def resolve_reference(cls, upc: str) -> "Product":
return models.Product.objects.get(upc=upc)
```
## Creating a Federated Schema
Use `strawberry.federation.Schema` instead of the regular `strawberry.Schema`:
```python
from strawberry.federation import Schema
@strawberry.type
class Query:
@strawberry_django.field
def products(self) -> list[Product]:
return models.Product.objects.all()
schema = Schema(query=Query)
```
## Django-Specific Considerations
### Query Optimizer
The [Query Optimizer](../guide/optimizer.md) works with federated schemas. Add the
extension as usual:
```python
from strawberry_django.optimizer import DjangoOptimizerExtension
schema = Schema(
query=Query,
extensions=[DjangoOptimizerExtension],
)
```
The auto-generated `resolve_reference` methods integrate with the query optimizer
when using `strawberry_django.federation`.
### Authentication
When using federation with Django authentication, ensure your gateway forwards
authentication headers. See [Authentication](../guide/authentication.md) for
configuring authentication in your Django service.
## Further Reading
For complete federation documentation, see:
- [Strawberry Federation Guide](https://strawberry.rocks/docs/guides/federation)
- [Federation Specification](https://www.apollographql.com/docs/federation/)
|