Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for GraphQL Multipart Uploads #158

Open
siopaonow opened this issue Aug 7, 2021 · 5 comments
Open

Add support for GraphQL Multipart Uploads #158

siopaonow opened this issue Aug 7, 2021 · 5 comments
Labels
enhancement New feature or request

Comments

@siopaonow
Copy link
Contributor

Wondering if it would be in the scope of this library support for GraphQL Multipart Uploads as per: https://github.com/jaydenseric/graphql-multipart-request-spec? More than happy to give writing an implementation a go and submittined a PR.

Reference Python implementations:

@florimondmanca
Copy link
Contributor

@siopaonow If I'm being honest, I'm not a user of GraphQL myself, and by extension not very familiar with usage patterns in the community, so:

Could you provide a full sample / minimal use case w/ code snippets demonstrating how we'd want this to be used, and how things would get plugged in together on the user side?

We'd need to clarify if this involves adding / changing public-facing APIs, and then decide what those should be.

@florimondmanca florimondmanca added the enhancement New feature or request label Aug 7, 2021
@siopaonow
Copy link
Contributor Author

I think this change should be able to be introuduced in a non-breaking way with an:

  • addition of the tartiflette_asgi.upload plugin module, to add the Upload scalar to the schema
  • addition of the upload=True flag to the TartifletteApp class to enable parsing of file uploads
  • adjustments to the GraphQLEndpoint to support multipart/form-data content-type and injection of uploaded files into the payload.

As for some examples on how this would be used on the users end:
Schema Definition Language (SDL)

from tartiflette import Resolver
from tartiflette_asgi import TartifletteApp

@Resolver("Query.file")
async def file(parent, args, context, info):
    uploaded_file = args["upload"]
    return uploaded_file.filename

sdl = "type Query { file(upload: Upload): String }"
app = TartifletteApp(sdl=sdl, upload=True)

Tartiflette Engine instance

from tartiflette import Engine

engine = Engine(
    sdl=...,
    modules=[
        "tartiflette_asgi.upload",
    ]
)

app = TartifletteApp(engine=engine, upload=True)

Let me know if anything is unclear or any further details are required.

@florimondmanca
Copy link
Contributor

Thanks for these pointers!

So, it's unclear to me if this should be in tartiflette-asgi, OR in tartiflette itself.

Things like "a scalar in the schema" are related to the GraphQL engine, rather than the web layer.

  • Does the aiohttp-based web layer support this already?
  • What would upload=True do exactly? Register something on thé engine? Enable decoding detected multipart inputs a certain way?

@siopaonow
Copy link
Contributor Author

I believe this has to be part of tartiflette-asgi, as prior to the query being executed by the engine, we need parse and 'mutate' the sent query to insert the upload files from the request. Details on the multipart structure can be found here and a few example requests can be found here. Hopefully that helps clarify.

In answer to your questions:

  • Does the aiohttp-based web layer support this already?
    No, it does not.
  • What would upload=True do exactly? Register something on thé engine? Enable decoding detected multipart inputs a certain way?
    Yes, correct. The flag would enable the decoding of multipart requests and the placement of the uploaded files into the query payload.

@florimondmanca
Copy link
Contributor

@siopaonow Thanks. I think at this point if you want to have a try at a draft PR to illustrate what that would look like, that would be a nice next step. :-) Let's remember that Starlette already has a multipart parser, available as await request.form(), so we don't need to reinvent that part.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants