python-3.xfastapistrawberry-graphql

Strawberry-FastAPI: How to call the right function?


I'm implementing a variation of the file upload in this tutorial:

https://strawberry.rocks/docs/guides/file-upload

The code is basically this:

import typing
import strawberry
from strawberry.file_uploads import Upload


@strawberry.input
class FolderInput:
    files: typing.List[Upload]

@strawberry.type
class Mutation:
    @strawberry.mutation
    async def read_file(self, file: Upload) -> str:
        [do some processing]
        return "Processing of PDF done!"

I test it with this invocation:

curl localhost:8000/graphql \
  -F operations='{ "query": "mutation($file: Upload!){ readFile(file: $file) }", "variables": { "file": null } }' \
  -F map='{ "file": ["variables.file"] }' \
  -F file=@/path/to/some_file.pdf

The CURL invocation calls readFile whereas the mutation in Strawberry uses read_file, where is that mapping done and can we control that? I'd like multiple read methods (e.g. read_typeA_pdf, read_typeB_pdf, etc).


Solution

  • To give my share of my knowledge on this is - the mapping between the GraphQL mutation name and the actual Python method name is handled by the Strawberry library itself

    As per your example, I would say the GraphQL mutation name is readFile, while the Python method name is read_file. Strawberry uses a snake_case naming convention to convert the GraphQL operation name to a Python method name

    you can try directly as below

    @strawberry.type
    class Mutation:
        @strawberry.mutation
        async def read_typeA_pdf(self, file: Upload) -> str:
            return "Processing of Type A PDF done!"
    
        @strawberry.mutation
        async def read_typeB_pdf(self, file: Upload) -> str:
            return "Processing of Type B PDF done!"
    

    Possibly, With these methods defined, you can now use the following GraphQL mutation names to invoke them like below:

    Invoking the read_typeA_pdf mutation with a Type A PDF file

    curl localhost:8000/graphql \
      -F operations='{ "query": "mutation($file: Upload!){ readTypeAPdf(file: $file) }", "variables": { "file": null } }' \
      -F map='{ "file": ["variables.file"] }' \
      -F file=@/path/to/typeA.pdf
    

    Invoking the read_typeB_pdf mutation with a Type B PDF file:

    curl localhost:8000/graphql \
      -F operations='{ "query": "mutation($file: Upload!){ readTypeBPdf(file: $file) }", "variables": { "file": null } }' \
      -F map='{ "file": ["variables.file"] }' \
      -F file=@/path/to/typeB.pdf
    

    You might replace /path/to/typeA.pdf and /path/to/typeB.pdf with the actual paths to your Type A and Type B PDF files, respectively.

    https://strawberry.rocks/docs/general/mutations

    Hope this helps.