Skip to content

Commit

Permalink
Document how to render a custom graphql IDE (#3664)
Browse files Browse the repository at this point in the history
  • Loading branch information
DoctorJohn authored Oct 7, 2024
1 parent 7feeea9 commit 0bc9773
Show file tree
Hide file tree
Showing 11 changed files with 238 additions and 17 deletions.
18 changes: 18 additions & 0 deletions docs/integrations/aiohttp.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ methods:
- `async get_root_value(self, request: aiohttp.web.Request) -> object`
- `async process_result(self, request: aiohttp.web.Request, result: ExecutionResult) -> GraphQLHTTPResponse`
- `def encode_json(self, data: GraphQLHTTPResponse) -> str`
- `async def render_graphql_ide(self, request: aiohttp.web.Request) -> aiohttp.web.Response`

### get_context

Expand Down Expand Up @@ -151,3 +152,20 @@ class MyGraphQLView(GraphQLView):
def encode_json(self, data: GraphQLHTTPResponse) -> str:
return json.dumps(data, indent=2)
```

### render_graphql_ide

In case you need more control over the rendering of the GraphQL IDE than the
`graphql_ide` option provides, you can override the `render_graphql_ide` method.

```python
from aiohttp import web
from strawberry.aiohttp.views import GraphQLView


class MyGraphQLView(GraphQLView):
async def render_graphql_ide(self, request: web.Request) -> web.Response:
custom_html = """<html><body><h1>Custom GraphQL IDE</h1></body></html>"""

return web.Response(text=custom_html, content_type="text/html")
```
18 changes: 18 additions & 0 deletions docs/integrations/asgi.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ We allow to extend the base `GraphQL` app, by overriding the following methods:
- `async get_root_value(self, request: Request) -> Any`
- `async process_result(self, request: Request, result: ExecutionResult) -> GraphQLHTTPResponse`
- `def encode_json(self, response_data: GraphQLHTTPResponse) -> str`
- `async def render_graphql_ide(self, request: Request) -> Response`

### get_context

Expand Down Expand Up @@ -176,3 +177,20 @@ class MyGraphQLView(GraphQL):
def encode_json(self, data: GraphQLHTTPResponse) -> str:
return json.dumps(data, indent=2)
```

### render_graphql_ide

In case you need more control over the rendering of the GraphQL IDE than the
`graphql_ide` option provides, you can override the `render_graphql_ide` method.

```python
from strawberry.asgi import GraphQL
from starlette.responses import HTMLResponse, Response


class MyGraphQL(GraphQL):
async def render_graphql_ide(self, request: Request) -> Response:
custom_html = """<html><body><h1>Custom GraphQL IDE</h1></body></html>"""

return HTMLResponse(custom_html)
```
18 changes: 18 additions & 0 deletions docs/integrations/chalice.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ We allow to extend the base `GraphQLView`, by overriding the following methods:
- `get_root_value(self, request: Request) -> Any`
- `process_result(self, request: Request, result: ExecutionResult) -> GraphQLHTTPResponse`
- `encode_json(self, response_data: GraphQLHTTPResponse) -> str`
- `def render_graphql_ide(self, request: Request) -> Response`

### get_context

Expand Down Expand Up @@ -161,3 +162,20 @@ class MyGraphQLView(GraphQLView):
def encode_json(self, data: GraphQLHTTPResponse) -> str:
return json.dumps(data, indent=2)
```

### render_graphql_ide

In case you need more control over the rendering of the GraphQL IDE than the
`graphql_ide` option provides, you can override the `render_graphql_ide` method.

```python
from strawberry.chalice.views import GraphQLView
from chalice.app import Request, Response


class MyGraphQLView(GraphQLView):
def render_graphql_ide(self, request: Request) -> Response:
custom_html = """<html><body><h1>Custom GraphQL IDE</h1></body></html>"""

return Response(custom_html, headers={"Content-Type": "text/html"})
```
21 changes: 19 additions & 2 deletions docs/integrations/channels.md
Original file line number Diff line number Diff line change
Expand Up @@ -533,9 +533,10 @@ We allow to extend `GraphQLHTTPConsumer`, by overriding the following methods:

- `async def get_context(self, request: ChannelsRequest, response: TemporalResponse) -> Context`
- `async def get_root_value(self, request: ChannelsRequest) -> Optional[RootValue]`
- `async def process_result(self, request: Request, result: ExecutionResult) -> GraphQLHTTPResponse:`.
- `async def process_result(self, request: Request, result: ExecutionResult) -> GraphQLHTTPResponse`.
- `async def render_graphql_ide(self, request: ChannelsRequest) -> ChannelsResponse`

### Context
#### Context

The default context returned by `get_context()` is a `dict` that includes the
following keys by default:
Expand All @@ -552,6 +553,22 @@ following keys by default:
errors (defaults to `200`)
- `headers`: Any additional headers that should be send with the response

#### render_graphql_ide

In case you need more control over the rendering of the GraphQL IDE than the
`graphql_ide` option provides, you can override the `render_graphql_ide` method.

```python
from strawberry.channels import GraphQLHTTPConsumer, ChannelsRequest, ChannelsResponse


class MyGraphQLHTTPConsumer(GraphQLHTTPConsumer):
async def render_graphql_ide(self, request: ChannelsRequest) -> ChannelsResponse:
custom_html = """<html><body><h1>Custom GraphQL IDE</h1></body></html>"""

return ChannelsResponse(content=custom_html, content_type="text/html")
```

## GraphQLWSConsumer (WebSockets / Subscriptions)

### Options
Expand Down
50 changes: 44 additions & 6 deletions docs/integrations/django.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,12 @@ encoding process.

We allow to extend the base `GraphQLView`, by overriding the following methods:

- `get_context(self, request: HttpRequest, response: HttpResponse) -> Any`
- `get_root_value(self, request: HttpRequest) -> Any`
- `process_result(self, request: HttpRequest, result: ExecutionResult) -> GraphQLHTTPResponse`
- `def get_context(self, request: HttpRequest, response: HttpResponse) -> Any`
- `def get_root_value(self, request: HttpRequest) -> Any`
- `def process_result(self, request: HttpRequest, result: ExecutionResult) -> GraphQLHTTPResponse`
- `def render_graphql_ide(self, request: HttpRequest) -> HttpResponse`

## get_context
### get_context

`get_context` allows to provide a custom context object that can be used in your
resolver. You can return anything here, by default we return a
Expand Down Expand Up @@ -101,7 +102,7 @@ called "example".
Then we use the context in a resolver, the resolver will return "1" in this
case.

## get_root_value
### get_root_value

`get_root_value` allows to provide a custom root value for your schema, this is
probably not used a lot but it might be useful in certain situations.
Expand All @@ -122,7 +123,7 @@ class Query:
Here we are returning a Query where the name is "Patrick", so we when requesting
the field name we'll return "Patrick" in this case.

## process_result
### process_result

`process_result` allows to customize and/or process results before they are sent
to the clients. This can be useful logging errors or hiding them (for example to
Expand Down Expand Up @@ -151,6 +152,24 @@ class MyGraphQLView(GraphQLView):
In this case we are doing the default processing of the result, but it can be
tweaked based on your needs.

### render_graphql_ide

In case you need more control over the rendering of the GraphQL IDE than the
`graphql_ide` option provides, you can override the `render_graphql_ide` method.

```python
from strawberry.django.views import GraphQLView
from django.http import HttpResponse
from django.template.loader import render_to_string


class MyGraphQLView(GraphQLView):
def render_graphql_ide(self, request: HttpRequest) -> HttpResponse:
content = render_to_string("myapp/my_graphql_ide_template.html")

return HttpResponse(content)
```

# Async Django

Strawberry also provides an async view that you can use with Django 3.1+
Expand Down Expand Up @@ -190,6 +209,7 @@ methods:
- `async get_root_value(self, request: HttpRequest) -> Any`
- `async process_result(self, request: HttpRequest, result: ExecutionResult) -> GraphQLHTTPResponse`
- `def encode_json(self, data: GraphQLHTTPResponse) -> str`
- `async def render_graphql_ide(self, request: HttpRequest) -> HttpResponse`

### get_context

Expand Down Expand Up @@ -277,6 +297,24 @@ class MyGraphQLView(AsyncGraphQLView):
return json.dumps(data, indent=2)
```

### render_graphql_ide

In case you need more control over the rendering of the GraphQL IDE than the
`graphql_ide` option provides, you can override the `render_graphql_ide` method.

```python
from strawberry.django.views import AsyncGraphQLView
from django.http import HttpResponse
from django.template.loader import render_to_string


class MyGraphQLView(AsyncGraphQLView):
async def render_graphql_ide(self, request: HttpRequest) -> HttpResponse:
content = render_to_string("myapp/my_graphql_ide_template.html")

return HttpResponse(content)
```

## Subscriptions

Subscriptions run over websockets and thus depend on
Expand Down
17 changes: 17 additions & 0 deletions docs/integrations/fastapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,3 +301,20 @@ class MyGraphQLRouter(GraphQLRouter):
def encode_json(self, data: GraphQLHTTPResponse) -> bytes:
return orjson.dumps(data)
```

### render_graphql_ide

In case you need more control over the rendering of the GraphQL IDE than the
`graphql_ide` option provides, you can override the `render_graphql_ide` method.

```python
from strawberry.fastapi import GraphQLRouter
from starlette.responses import HTMLResponse, Response


class MyGraphQLRouter(GraphQLRouter):
async def render_graphql_ide(self, request: Request) -> HTMLResponse:
custom_html = """<html><body><h1>Custom GraphQL IDE</h1></body></html>"""

return HTMLResponse(custom_html)
```
26 changes: 22 additions & 4 deletions docs/integrations/flask.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ The `GraphQLView` accepts the following options at the moment:

We allow to extend the base `GraphQLView`, by overriding the following methods:

- `get_context(self, request: Request, response: Response) -> Any`
- `get_root_value(self, request: Request) -> Any`
- `process_result(self, result: ExecutionResult) -> GraphQLHTTPResponse`
- `encode_json(self, response_data: GraphQLHTTPResponse) -> str`
- `def get_context(self, request: Request, response: Response) -> Any`
- `def get_root_value(self, request: Request) -> Any`
- `def process_result(self, result: ExecutionResult) -> GraphQLHTTPResponse`
- `def encode_json(self, response_data: GraphQLHTTPResponse) -> str`
- `def render_graphql_ide(self, request: Request) -> Response`

<Note>

Expand Down Expand Up @@ -148,3 +149,20 @@ class MyGraphQLView(GraphQLView):
def encode_json(self, data: GraphQLHTTPResponse) -> str:
return json.dumps(data, indent=2)
```

### render_graphql_ide

In case you need more control over the rendering of the GraphQL IDE than the
`graphql_ide` option provides, you can override the `render_graphql_ide` method.

```python
from strawberry.flask.views import GraphQLView
from flask import Request, Response


class MyGraphQLView(GraphQLView):
def render_graphql_ide(self, request: Request) -> Response:
custom_html = """<html><body><h1>Custom GraphQL IDE</h1></body></html>"""

return Response(custom_html, status=200, content_type="text/html")
```
40 changes: 40 additions & 0 deletions docs/integrations/litestar.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,3 +317,43 @@ GraphQLController = make_graphql_controller(

app = Litestar(route_handlers=[GraphQLController])
```

## Extending the controller

The `make_graphql_controller` function returns a `GraphQLController` class that
can be extended by overriding the following methods:

1. `async def render_graphql_ide(self, request: Request) -> Response`

### render_graphql_ide

In case you need more control over the rendering of the GraphQL IDE than the
`graphql_ide` option provides, you can override the `render_graphql_ide` method.

```python
import strawberry
from strawberry.litestar import make_graphql_controller
from litestar import MediaType, Request, Response


@strawberry.type
class Query:
@strawberry.field
def hello(self) -> str:
return "world"


schema = strawberry.Schema(Query)

GraphQLController = make_graphql_controller(
schema,
path="/graphql",
)


class MyGraphQLController(GraphQLController):
async def render_graphql_ide(self, request: Request) -> Response:
custom_html = """<html><body><h1>Custom GraphQL IDE</h1></body></html>"""

return Response(custom_html, media_type=MediaType.HTML)
```
26 changes: 22 additions & 4 deletions docs/integrations/quart.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ The `GraphQLView` accepts the following options at the moment:

We allow to extend the base `GraphQLView`, by overriding the following methods:

- `get_context(self, request: Request, response: Response) -> Any`
- `get_root_value(self, request: Request) -> Any`
- `process_result(self, result: ExecutionResult) -> GraphQLHTTPResponse`
- `encode_json(self, response_data: GraphQLHTTPResponse) -> str`
- `async def get_context(self, request: Request, response: Response) -> Any`
- `async def get_root_value(self, request: Request) -> Any`
- `async def process_result(self, result: ExecutionResult) -> GraphQLHTTPResponse`
- `def encode_json(self, response_data: GraphQLHTTPResponse) -> str`
- `async def render_graphql_ide(self, request: Request) -> Response`

### get_context

Expand Down Expand Up @@ -132,3 +133,20 @@ class MyGraphQLView(GraphQLView):
def encode_json(self, data: GraphQLHTTPResponse) -> str:
return json.dumps(data, indent=2)
```

### render_graphql_ide

In case you need more control over the rendering of the GraphQL IDE than the
`graphql_ide` option provides, you can override the `render_graphql_ide` method.

```python
from strawberry.quart.views import GraphQLView
from quart import Request, Response


class MyGraphQLView(GraphQLView):
async def render_graphql_ide(self, request: Request) -> Response:
custom_html = """<html><body><h1>Custom GraphQL IDE</h1></body></html>"""

return Response(self.graphql_ide_html)
```
19 changes: 19 additions & 0 deletions docs/integrations/sanic.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ methods:
- `async get_context(self, request: Request, response: Response) -> Any`
- `async get_root_value(self, request: Request) -> Any`
- `async process_result(self, result: ExecutionResult) -> GraphQLHTTPResponse`
- `async def render_graphql_ide(self, request: Request) -> HTTPResponse`

### get_context

Expand Down Expand Up @@ -130,3 +131,21 @@ class MyGraphQLView(GraphQLView):
def encode_json(self, data: GraphQLHTTPResponse) -> str:
return json.dumps(data, indent=2)
```

### render_graphql_ide

In case you need more control over the rendering of the GraphQL IDE than the
`graphql_ide` option provides, you can override the `render_graphql_ide` method.

```python
from strawberry.sanic.views import GraphQLView
from sanic.request import Request
from sanic.response import HTTPResponse, html


class MyGraphQLView(GraphQLView):
async def render_graphql_ide(self, request: Request) -> HTTPResponse:
custom_html = """<html><body><h1>Custom GraphQL IDE</h1></body></html>"""

return html(custom_html)
```
2 changes: 1 addition & 1 deletion strawberry/asgi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ async def get_sub_response(

return sub_response

async def render_graphql_ide(self, request: Union[Request, WebSocket]) -> Response:
async def render_graphql_ide(self, request: Request) -> Response:
return HTMLResponse(self.graphql_ide_html)

def create_response(
Expand Down

0 comments on commit 0bc9773

Please sign in to comment.