diff --git a/file-upload/README.md b/file-upload/README.md new file mode 100644 index 0000000..1cb112c --- /dev/null +++ b/file-upload/README.md @@ -0,0 +1,31 @@ +# File Upload +This Spring example shows how the upload operation works using GraphQL and the Apollo Upload type. + +## How to run +- Create a file: `echo 'Hello World!' > hello-world.txt` +- Run the example: `../gradlew bootRun` +- Make a GraphQL request: +```sh +curl --location 'http://localhost:9000/graphql' \ + --form 'operations="{\"query\": \"mutation upload($file:Upload){ upload(file: $file){filename type content}}\"}"' \ + --form 'map="{\"blob\": [\"variables.file\"]}"' \ + --form 'blob=@"./hello-world.txt"' +``` + +If the file is successfully uploaded, this is the response received and the log shown: +```json +{ + "data": { + "upload": { + "filename": "hello-world.txt", + "type": "text/plain", + "content": "Hello World!\n" + } + } +} + +``` + +```log +INFO 1584868 --- [nio-9000-exec-7] upload.UploadMutation: File uploaded: {type=text/plain, filename=hello-world.txt, content=Hello World!} +``` diff --git a/file-upload/src/main/java/upload/Query.java b/file-upload/src/main/java/upload/Query.java index aba1ba9..008ee30 100644 --- a/file-upload/src/main/java/upload/Query.java +++ b/file-upload/src/main/java/upload/Query.java @@ -4,4 +4,10 @@ import org.springframework.stereotype.Service; @Service -class Query implements GraphQLQueryResolver {} +class Query implements GraphQLQueryResolver { + + // This query is necessary because the graphql-java-tool requires at least one query + public String getHello() { + return "Hello World"; + } +} diff --git a/file-upload/src/main/java/upload/UploadMutation.java b/file-upload/src/main/java/upload/UploadMutation.java index a621c10..b0470da 100644 --- a/file-upload/src/main/java/upload/UploadMutation.java +++ b/file-upload/src/main/java/upload/UploadMutation.java @@ -2,6 +2,8 @@ import graphql.kickstart.tools.GraphQLMutationResolver; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Map; import javax.servlet.http.Part; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -10,9 +12,13 @@ @Service class UploadMutation implements GraphQLMutationResolver { - boolean upload(Part part) throws IOException { - log.info("Part: {}", part.getSubmittedFileName()); - part.write(part.getSubmittedFileName()); - return true; + Map upload(Part part) throws IOException { + Map uploadedFile = Map.of( + "filename", part.getSubmittedFileName(), + "type", part.getContentType(), + "content", new String(part.getInputStream().readAllBytes(), StandardCharsets.UTF_8) + ); + log.info("File uploaded: {}", uploadedFile); + return uploadedFile; } } diff --git a/file-upload/src/main/resources/schema.graphqls b/file-upload/src/main/resources/schema.graphqls index 7bc1288..7b3cc42 100644 --- a/file-upload/src/main/resources/schema.graphqls +++ b/file-upload/src/main/resources/schema.graphqls @@ -1,9 +1,16 @@ scalar Upload -type Query { +type UploadedFile { + filename: String + type: String + content: String +} +# The hello query declaration is necessary since the graphql-java-tools requires at least one query +type Query { + hello: String } type Mutation { - upload(file: Upload): Boolean + upload(file: Upload): UploadedFile }