Skip to content

Parameters

Of course, we expect that queries and mutation should accept parameters, and of course, FastGraphQL gives us an easy way to deal with them.

Putting semantics aside, FastGraphQL handles queries and mutations in the same way and everything we need to ensure that all parameters and return values have type hints

Heads Up!

To simplify documentation, remember that both method signatures, FastGraphQL.query() and FastGraphQL.mutation(), have the same signature and therefore we will use only FastGraphQL.query() in the next examples.

Query and Mutation Parameters

This is our starting point for this section. Starting from the following file:

main.py
from fastapi import FastAPI
from fastgraphql import FastGraphQL
from fastgraphql.fastapi import make_ariadne_fastapi_router
from pydantic import BaseModel

app = FastAPI()
fast_graphql = FastGraphQL()


@fast_graphql.query()
def hello_query(name: str) -> str:
    return f"Hello {name}!!!"


class Model(BaseModel):
    value: str


class QueryInput(BaseModel):
    value: str


@fast_graphql.query()
def model_query(input: QueryInput) -> Model:
    return Model(value=input.value)


app.include_router(make_ariadne_fastapi_router(fast_graphql=fast_graphql))

execute:

$ uvicorn main:app --reload

and open http://127.0.0.1:8000/graphql

to see something like:

Image

Deep-Dive 🤿

Scalar Input and Output

The first initial type of parameters is parameters using scalar types, or python primitive types. (See Type System and Python Types)

main.py
from fastapi import FastAPI
from fastgraphql import FastGraphQL
from fastgraphql.fastapi import make_ariadne_fastapi_router
from pydantic import BaseModel

app = FastAPI()
fast_graphql = FastGraphQL()


@fast_graphql.query()
def hello_query(name: str) -> str:
    return f"Hello {name}!!!"


class Model(BaseModel):
    value: str


class QueryInput(BaseModel):
    value: str


@fast_graphql.query()
def model_query(input: QueryInput) -> Model:
    return Model(value=input.value)


app.include_router(make_ariadne_fastapi_router(fast_graphql=fast_graphql))

Looking into lines 10 until 12, the simplest way to define an str parameter is to declare a parameter in your query or mutation method as shown in line 11. In the same way, to define the output type of a query or mutation, just annotate the return type of the function, also in line 11.

Complex Input and Output

main.py
from fastapi import FastAPI
from fastgraphql import FastGraphQL
from fastgraphql.fastapi import make_ariadne_fastapi_router
from pydantic import BaseModel

app = FastAPI()
fast_graphql = FastGraphQL()


@fast_graphql.query()
def hello_query(name: str) -> str:
    return f"Hello {name}!!!"


class Model(BaseModel):
    value: str


class QueryInput(BaseModel):
    value: str


@fast_graphql.query()
def model_query(input: QueryInput) -> Model:
    return Model(value=input.value)


app.include_router(make_ariadne_fastapi_router(fast_graphql=fast_graphql))

Now looking into lines 23 until 25, we can define an input type called QueryInput. Note that QueryInput is pydantic model supported by FastGraphQL.

In the same way, we can define an output type, which is also pydantic model, called Model.

FastGraphQL allows you to define implicit GraphQL inputs and types. Note that neither Model nor QueryInput has any decorator, nevertheless, FastGraphQL understands both classes as GraphQL type and input respectively.

Reusing Classes

There are many circumstances in which input and output are the same, meaning we could use the same class. This is possible with FastGraphQL. Let us rewrite the code above as follows:

main.py
from fastapi import FastAPI
from fastgraphql import FastGraphQL
from fastgraphql.fastapi import make_ariadne_fastapi_router
from pydantic import BaseModel

app = FastAPI()
fast_graphql = FastGraphQL()


@fast_graphql.input(name="ModelInput")
class Model(BaseModel):
    value: str


@fast_graphql.query()
def model_query(input: Model) -> Model:
    return Model(value=input.value)


app.include_router(make_ariadne_fastapi_router(fast_graphql=fast_graphql))

Looking at line 16, we have now the same python class serving as the input and output of this specific query. As an outcome we have:

Image

Note that line 10 is a key aspect of this construct. This line tells FastGraphQL that we want to use the class Model as an input named ModelInput. Since we are using implicit definitions, this avoids FastGraphQL throwing an error telling us that we have two GraphQL entities, one input and one type in this case, with the same name.