mirumee / ariadne

Python library for implementing GraphQL servers using schema-first approach.
https://ariadnegraphql.org
BSD 3-Clause "New" or "Revised" License
2.23k stars 179 forks source link

OpenAPI schema for ariadne routes is not generated by starlette #975

Open and3rson opened 2 years ago

and3rson commented 2 years ago

We're trying to generate an OpenAPI schema using starlette.schemas.SchemaGenerator, however it does not include any definitions for ariadne.

As per starlette's docs:

Schema generation works by inspecting the routes on the application through app.routes, and using the docstrings or other attributes on the endpoints in order to determine a complete API schema.

Is it possible to add a docstring into ariadne's graphql endpoint, or allow it to be configured manually so that it can be picked up by ariadne's schema generator?

EDIT: One possible workaround is to wrap ariadne's route with another route, but it would be great if this was available out of the box. EDIT 2: Seems like SchemaGenerator.get_endpoints doesn't find ariadne's endpoints. We're using it as follows:

class GraphQLAdapter(Starlette):
    SCHEMA_PATH = ...

    def __init__(self):
        ...
        schema = make_executable_schema(...)
        graphql = GraphQL(schema)

        super().__init__(
            routes=[
                Mount('', graphql),
            ],
        )
rafalp commented 2 years ago

I'm not familiar with how schema generation works in Starlette. Is it possible to have a method on mounted ASGI application that would return this data for Starlette?

and3rson commented 2 years ago

@rafalp It seems like starlette attempts to fetch routes attribute from the mounted app, however ariadne doesn't have any:

https://github.com/encode/starlette/blob/master/starlette/schemas.py#L54 https://github.com/encode/starlette/blob/master/starlette/routing.py#L384

...so it seems that starlette won't be able to introspect ariadne's routes unless ariadne exposes some routes.

route = Mount('', graphql)
print(route.routes)  # Empty: https://github.com/encode/starlette/blob/master/starlette/routing.py#L384

schemas = SchemaGenerator({})
schemas.get_endpoints(route.routes)  # Empty: https://github.com/encode/starlette/blob/master/starlette/schemas.py#L54
and3rson commented 2 years ago

@rafalp - It looks like there's little ariadne can do here, since it's an app, not just a route. Possibly a better solution to this would be to actually submit a feature proposal for starlette to make SchemaGenerator call some method on the mounted app which will return the docstring.

rafalp commented 2 years ago

We could potentially create property(routes) and use that, but then we will have an ASGI app that creates Starlette routes that wrap its methods and that doesn't sound like good approach to me.

and3rson commented 2 years ago

@rafalp - totally agree. This sounds like something that needs to be done in starlette. I've started a discussion for this: https://github.com/encode/starlette/discussions/1958