Skip to content

Commit

Permalink
馃摑 Update GraphQL docs, recommend Strawberry (#3981)
Browse files Browse the repository at this point in the history
  • Loading branch information
tiangolo committed Oct 3, 2021
1 parent 1db0fc2 commit 4b968c4
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 39 deletions.
3 changes: 1 addition & 2 deletions README.md
Expand Up @@ -418,9 +418,9 @@ For a more complete example including more features, see the <a href="https://fa
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* **GraphQL** integration with <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> and other libraries.
* Many extra features (thanks to Starlette) as:
* **WebSockets**
* **GraphQL**
* extremely easy tests based on `requests` and `pytest`
* **CORS**
* **Cookie Sessions**
Expand All @@ -447,7 +447,6 @@ Used by Starlette:
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
* <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - Required for `GraphQLApp` support.
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.

Used by FastAPI / Starlette:
Expand Down
1 change: 0 additions & 1 deletion docs/de/docs/features.md
Expand Up @@ -167,7 +167,6 @@ Mit **FastAPI** bekommen Sie viele von **Starlette**'s Funktionen (da FastAPI nu

* Stark beeindruckende Performanz. Es ist <a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank">eines der schnellsten Python frameworks, auf Augenh枚he mit **NodeJS** und **Go**</a>.
* **WebSocket**-Unterst眉tzung.
* **GraphQL**-Unterst眉tzung.
* Hintergrundaufgaben im selben Prozess.
* Ereignisse f眉r das Starten und Herunterfahren.
* Testclient basierend auf `requests`.
Expand Down
2 changes: 0 additions & 2 deletions docs/de/docs/index.md
Expand Up @@ -425,7 +425,6 @@ For a more complete example including more features, see the <a href="https://fa
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* Many extra features (thanks to Starlette) as:
* **WebSockets**
* **GraphQL**
* extremely easy tests based on `requests` and `pytest`
* **CORS**
* **Cookie Sessions**
Expand All @@ -452,7 +451,6 @@ Used by Starlette:
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
* <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - Required for `GraphQLApp` support.
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.

Used by FastAPI / Starlette:
Expand Down
56 changes: 34 additions & 22 deletions docs/en/docs/advanced/graphql.md
@@ -1,44 +1,56 @@
# GraphQL

**FastAPI** has optional support for GraphQL (provided by Starlette directly), using the `graphene` library.
As **FastAPI** is based on the **ASGI** standard, it's very easy to integrate any **GraphQL** library also compatible with ASGI.

You can combine normal FastAPI *path operations* with GraphQL on the same application.

## Import and use `graphene`
!!! tip
**GraphQL** solves some very specific use cases.

GraphQL is implemented with Graphene, you can check <a href="https://docs.graphene-python.org/en/latest/quickstart/" class="external-link" target="_blank">Graphene's docs</a> for more details.
It has **advantages** and **disadvantages** when compared to common **web APIs**.

Import `graphene` and define your GraphQL data:
Make sure you evaluate if the **benefits** for your use case compensate the **drawbacks**. 馃

```Python hl_lines="1 6-10"
{!../../../docs_src/graphql/tutorial001.py!}
```
## GraphQL Libraries

Here are some of the **GraphQL** libraries that have **ASGI** support. You could use them with **FastAPI**:

* <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry</a> 馃崜
* With <a href="https://strawberry.rocks/docs/integrations/fastapi" class="external-link" target="_blank">docs for FastAPI</a>
* <a href="https://ariadnegraphql.org/" class="external-link" target="_blank">Ariadne</a>
* With <a href="https://ariadnegraphql.org/docs/starlette-integration" class="external-link" target="_blank">docs for Starlette</a> (that also apply to FastAPI)
* <a href="https://tartiflette.io/" class="external-link" target="_blank">Tartiflette</a>
* With <a href="https://tartiflette.github.io/tartiflette-asgi/" class="external-link" target="_blank">Tartiflette ASGI</a> to provide ASGI integration
* <a href="https://graphene-python.org/" class="external-link" target="_blank">Graphene</a>
* With <a href="https://github.com/ciscorn/starlette-graphene3" class="external-link" target="_blank">starlette-graphene3</a>

## GraphQL with Strawberry

If you need or want to work with **GraphQL**, <a href="https://strawberry.rocks/" class="external-link" target="_blank">**Strawberry**</a> is the **recommended** library as it has the design closest to **FastAPI's** design, it's all based on **type annotations**.

## Add Starlette's `GraphQLApp`
Depending on your use case, you might prefer to use a different library, but if you asked me, I would probably suggest you try **Strawberry**.

Then import and add Starlette's `GraphQLApp`:
Here's a small preview of how you could integrate Strawberry with FastAPI:

```Python hl_lines="3 14"
```Python hl_lines="3 22 25-26"
{!../../../docs_src/graphql/tutorial001.py!}
```

!!! info
Here we are using `.add_route`, that is the way to add a route in Starlette (inherited by FastAPI) without declaring the specific operation (as would be with `.get()`, `.post()`, etc).
You can learn more about Strawberry in the <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry documentation</a>.

## Check it
And also the docs about <a href="https://strawberry.rocks/docs/integrations/fastapi" class="external-link" target="_blank">Strawberry with FastAPI</a>.

Run it with Uvicorn and open your browser at <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
## Older `GraphQLApp` from Starlette

You will see GraphiQL web user interface:
Previous versions of Starlette included a `GraphQLApp` class to integrate with <a href="https://graphene-python.org/" class="external-link" target="_blank">Graphene</a>.

<img src="/img/tutorial/graphql/image01.png">
It was deprecated from Starlette, but if you have code that used it, you can easily **migrate** to <a href="https://github.com/ciscorn/starlette-graphene3" class="external-link" target="_blank">starlette-graphene3</a>, that covers the same use case and has an **almost identical interface**.

## More details
!!! tip
If you need GraphQL, I still would recommend you check out <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry</a>, as it's based on type annotations instead of custom classes and types.

For more details, including:
## Learn More

* Accessing request information
* Adding background tasks
* Using normal or async functions
You can learn more about **GraphQL** in the <a href="https://graphql.org/" class="external-link" target="_blank">official GraphQL documentation</a>.

check the official <a href="https://www.starlette.io/graphql/" class="external-link" target="_blank">Starlette GraphQL docs</a>.
You can also read more about each those libraries described above in their links.
3 changes: 1 addition & 2 deletions docs/en/docs/alternatives.md
Expand Up @@ -367,15 +367,14 @@ It has:

* Seriously impressive performance.
* WebSocket support.
* GraphQL support.
* In-process background tasks.
* Startup and shutdown events.
* Test client built on requests.
* CORS, GZip, Static Files, Streaming responses.
* Session and Cookie support.
* 100% test coverage.
* 100% type annotated codebase.
* Zero hard dependencies.
* Few hard dependencies.

Starlette is currently the fastest Python framework tested. Only surpassed by Uvicorn, which is not a framework, but a server.

Expand Down
1 change: 0 additions & 1 deletion docs/en/docs/features.md
Expand Up @@ -164,7 +164,6 @@ With **FastAPI** you get all of **Starlette**'s features (as FastAPI is just Sta

* Seriously impressive performance. It is <a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank">one of the fastest Python frameworks available, on par with **NodeJS** and **Go**</a>.
* **WebSocket** support.
* **GraphQL** support.
* In-process background tasks.
* Startup and shutdown events.
* Test client built on `requests`.
Expand Down
3 changes: 1 addition & 2 deletions docs/en/docs/index.md
Expand Up @@ -419,9 +419,9 @@ For a more complete example including more features, see the <a href="https://fa
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* **GraphQL** integration with <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> and other libraries.
* Many extra features (thanks to Starlette) as:
* **WebSockets**
* **GraphQL**
* extremely easy tests based on `requests` and `pytest`
* **CORS**
* **Cookie Sessions**
Expand All @@ -448,7 +448,6 @@ Used by Starlette:
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
* <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - Required for `GraphQLApp` support.
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.

Used by FastAPI / Starlette:
Expand Down
26 changes: 19 additions & 7 deletions docs_src/graphql/tutorial001.py
@@ -1,14 +1,26 @@
import graphene
import strawberry
from fastapi import FastAPI
from starlette.graphql import GraphQLApp
from strawberry.asgi import GraphQL


class Query(graphene.ObjectType):
hello = graphene.String(name=graphene.String(default_value="stranger"))
@strawberry.type
class User:
name: str
age: int

def resolve_hello(self, info, name):
return "Hello " + name

@strawberry.type
class Query:
@strawberry.field
def user(self) -> User:
return User(name="Patrick", age=100)


schema = strawberry.Schema(query=Query)


graphql_app = GraphQL(schema)

app = FastAPI()
app.add_route("/", GraphQLApp(schema=graphene.Schema(query=Query)))
app.add_route("/graphql", graphql_app)
app.add_websocket_route("/graphql", graphql_app)

0 comments on commit 4b968c4

Please sign in to comment.