使用GraphQL + Java处理上传的文件
概述
-
- JavaでGraphQLサーバーを構築した際のファイルアップロード処理の実装例
- GraphQLクライアント側の説明は割愛
组成
-
- Java 11
-
- SpringBoot 2.3.4
-
- gradle 7.4.1
-
- GraphQL For Java
graphql-spring-boot-starter 7.1.0 ref. 1
io.github.kobylynskyi.graphql.codegen 5.5.0
※ 注意,此配置不是最新的Spring Boot。
实施方式
点数 shù)
-
- schema定義について
GraphQLのschema定義ではアップロードするファイルをUploadで定義する
Uploadは、Java側で任意のクラスにマッピングするため、scalarに記載する
Java側について
schema定義のUploadをjavax.servlet.http.Partで受け取る
具体细节
- 全ソースはここからどうぞ
准备各种设置文件
-
- 创建基于Spring Initializr的项目
-
- 在build.gradle中如下所示进行编写
build.gradle
插件 {
id ‘org.springframework.boot’版本’2.3.4.RELEASE’
id ‘io.spring.dependency-management’版本’1.0.15.RELEASE’
id ‘io.github.kobylynskyi.graphql.codegen’版本’5.5.0’
id ‘java’
}
组 = ‘com.example’
版本 = ‘0.0.1-SNAPSHOT’
源兼容性 = ’11’
仓库 {
中央存储库()
}
依赖关系 {
实现 ‘org.springframework.boot:spring-boot-starter’
测试实现 ‘org.springframework.boot:spring-boot-starter-test’
实现 ‘com.graphql-java-kickstart:graphql-spring-boot-starter:7.1.0’
测试实现 ‘com.graphql-java-kickstart:graphql-spring-boot-starter:7.1.0’
}
任务的名称(’测试’) {
使用JUnit Platform()
}
由于URL等使用默认设置,因此application.properties不需要更改,参考2。
创建文件上传的schema定义。
-
- 以下是中文翻译:
graphql/schema.graphqls
”’
上传文件
”’
标量 Upload
# 在本示例中,Query 没有被使用,但如果不写它,应用程序在启动时会抱怨,所以需要添加这段
type Query {}
type Mutation {
”’
上传文件
”’
upload(
”’
文件
”’
file: Upload
): Boolean
}
从schema定义生成Java的接口和类
-
- 可以通过手动创建,但这次我们将使用graphql-java-codegen生成。ref. 4
在build.gradle中添加以下配置
build.gradle
// 在末尾添加
// 从GraphQL schema定义生成Java代码
apply from: ‘gradle/graphql-java-codegen.gradle’
创建配置文件graphql-java-codegen.gradle,并对在schema.graphqls中定义的标量类型(比如Upload)进行映射等配置 ref. 3,ref. 5
gradle/graphql-java-codegen.gradle
apply plugin: “io.github.kobylynskyi.graphql.codegen”
compileJava.options.encoding = ‘UTF-8’
graphqlCodegen {
// 所有配置选项:
// https://github.com/kobylynskyi/graphql-java-codegen/blob/master/docs/codegen-options.md
outputDir = new File(“$buildDir/generated”)
graphqlSchemas.includePattern = “schema\\.graphqls”
apiPackageName = “com.example.demographqlfileupload.graphql.resolvers”
// 通常情况下,model应该存在,但在本示例中不存在,因此不指定
//modelPackageName = “com.example.demographqlfileupload.graphql.model”
modelNameSuffix = “TO”
// 标量的映射类
customTypesMapping = [
Upload: “javax.servlet.http.Part”
]
parentInterfaces {
queryResolver = “graphql.kickstart.tools.GraphQLQueryResolver”
mutationResolver = “graphql.kickstart.tools.GraphQLMutationResolver”
}
}
使用以上配置文件执行以下gradle命令生成文件。
gradle graphqlCodegen -Dfile.encoding=utf-8
文件将生成在$buildDir/generated目录下,将文件移动到项目的任意文件夹下。这次移动到以下文件夹下:
/demographqlfileupload/src/main/java/com/example/demographqlfileupload/graphql/resolvers
生成的文件如下,将其复制到项目中
UploadMutationResolver.java
package com.example.demographqlfileupload.graphql.resolvers;
/**
* 上传文件
*/
@javax.annotation.processing.Generated(
value = “com.kobylynskyi.graphql.codegen.GraphQLCodegen”,
date = “2022-10-25T19:12:40+0900”
)
public interface UploadMutationResolver extends graphql.kickstart.tools.GraphQLMutationResolver {
/**
* 上传文件
*/
Boolean upload(javax.servlet.http.Part file) throws Exception;
}
明确表明从scalar到转换
-
- 以下是一个创建ExtendedScalarConfiguration类的示例:
“`java
package com.example.demographqlfileupload.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import graphql.kickstart.servlet.apollo.ApolloScalars;
import graphql.schema.GraphQLScalarType;
@Configuration
public class ExtendedScalarConfiguration {
@Bean
public GraphQLScalarType uploadScalar() {
return ApolloScalars.Upload;
}
}
“`
使用在步骤③生成的接口来创建解析器类。
-
- 创建以下类:
UploadResolver
package com.example.demographqlfileupload.resolver;
import javax.servlet.http.Part;
import org.springframework.stereotype.Component;
import com.example.demographqlfileupload.graphql.resolvers.QueryResolver;
import com.example.demographqlfileupload.graphql.resolvers.UploadMutationResolver;
@Component
public class UploadResolver
implements UploadMutationResolver, QueryResolver {
@Override
public Boolean upload(Part file) throws Exception {
if (Objects.isNull(file)) {
return false;
}
System.out.println(file.getSubmittedFileName());
return null;
}
}
确保你能够适当地进行文件处理,以完成任务!
确认动作
-
- いろいろGraphQLクライアントはあると思いますが、私はPostmanで統一したいのでPostmanを使っています。
- ファイルアップロードについては癖があるので注意
邮递员步骤参考7号。

总结
-
- GraphQLのschema定義scalarでUploadを指定する
-
- Java側ではschema定義のUploadをjavax.servlet.http.Partで受け取れるようマッピングしてやる
- SpringBootのバージョンによって取得するGraphQLのDependenciesが変わっているので注意!!
其他
-
- GraphQLはアップロードはサポートしていますがダウンロードに使うのは想定されていないようです。自前で実装しましょう。
Springならコントローラーを追加して通常のHttpRequestとして処理すればOK
Spring Boot 2.7 以降はSpring InitializrでSpring for GraphQLというDependenciesを利用することができます。提供されるパッケージが変わるため本稿の実装はそのままは使えないです。
例えば本稿ではgraphql.kickstartのパッケージを利用していますが、バージョンによってはこのパッケージは提供されていないため利用できなくなります。ref. 8, ref. 9, ref. 10
提供的信息参考
我只需要一个中文的选项来将下面的内容进行释义:
引用部
-
- ref. 1 GraphQL Java Kickstart
-
- ref. 2 Enable GraphQL Servlet
-
- ref. 3 How to upload files with graphql-java
-
- ref. 4 kobylynskyi/graphql-java-codegen
-
- ref. 5 graphql-java-codegen/docs/codegen-options.md
-
- ref. 6 Custom Scalar実装(GraphQL-SpringBoot)
-
- ref. 7 Is there any way to upload files via postman into a GraphQL API?
-
- ref. 8 GraphQL with spring-boot-starter-graphql
-
- ref. 9 Spring for GraphQL Documentation
- ref. 10 Getting started with Spring for GraphQL
整体来说
-
- Spring BootでGraphQLを試した
- Uploading files with Spring and GraphQL