When using the REST API functionality of a framework like FastAPI, it automatically generates the Openapi/Swagger with details of all constraints for each field as defined in the Pydantic models i.e. minLength, maxLength, minimum.
This is useful because anybody viewing the openapi/swagger can automatically know everything about the fields without any communication with the team who owns the API.
It would be great if @strawberry.experimental.pydantic would automatically generate a description for each field based off the underlying Pydantic field's constraints. This way people can view all constraints/validations on a field within the GraphIQL documentation explorer. I think this would be pretty innovative in terms of bridging the gap between OpenAPI/Swagger and GraphIQL as I haven't seen this functionality anywhere else.
We can use the underlying Pydantic schema of a Strawberry type to auto-generate a description string during application startup.
Working example of doing this manually with a couple of the many potential constraints Pydantic can handle:
from fastapi import FastAPI
from pydantic import Field, BaseModel
import strawberry
from strawberry.fastapi import GraphQLRouter
from storage.api.open_api import OpenApi
class User(BaseModel):
name: str = Field(max_length=50)
address: str = Field(max_length=100)
@strawberry.experimental.pydantic.type(model=User, all_fields=True)
class UserType:
pass
# 1. Get underlying pydantic schema which contains openapi information
pydantic_schema = UserType._pydantic_type.schema()
properties = pydantic_schema["properties"]
# 2. Loop through all the fields in the strawberry type
for i, field in enumerate(UserType._type_definition.fields):
# 3. Get maxLength/minLength from the underlying pydantic schema. In reality we'd get all possible constraitns
max_length = properties[field.name].get("maxLength")
min_length = properties[field.name].get("minLength")
# 4. Add the details to the field level description
description = f"maxLength: {max_length} \nminLength: {min_length}\n"
UserType._type_definition.fields[i].description = description
@strawberry.type
class Query:
@strawberry.field
def user(self) -> UserType:
user = User(name="Jeff", address="1234 Drury Lane")
return user
schema = strawberry.Schema(Query)
graphql_app = GraphQLRouter(schema)
app = FastAPI()
app = FastAPI(title=OpenApi.title, description=OpenApi.description)
app.include_router(graphql_app, prefix="/graphql")
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too