使用Apollo Kotlin向GraphQL服务器上传图片:求可行示例
Android 向 GraphQL 服务器上传图片可行实现示例
1. 依赖配置
在模块级 build.gradle 中添加 Apollo GraphQL 核心库及上传支持库:
dependencies { // Apollo GraphQL 核心运行库 implementation("com.apollographql.apollo3:apollo-runtime:3.8.2") // 上传功能扩展库 implementation("com.apollographql.apollo3:apollo-upload:3.8.2") }
2. 定义上传用的 GraphQL Mutation
创建 .graphql 文件,编写上传图片的 mutation:
mutation UploadImage($file: Upload!) { uploadImage(file: $file) { id url message } }
通过 Apollo 代码生成工具自动生成对应的 Kotlin 调用类(确保已配置 Apollo 插件开启代码生成)。
3. Android 端上传代码实现
配置 ApolloClient
初始化 ApolloClient 时必须添加上传拦截器,处理 multipart/form-data 类型请求:
val apolloClient = ApolloClient.Builder() .serverUrl("https://你的GraphQL服务器地址/graphql") .addInterceptor(ApolloUploadInterceptor()) .build()
上传函数实现
编写协程函数处理图片上传逻辑:
suspend fun uploadImage(imageFile: File): UploadImageMutation.Data? { return try { // 包装图片文件为 Upload 对象,指定文件名和 contentType val upload = Upload.Builder() .file(imageFile) .filename(imageFile.name) .contentType("image/jpeg") // 图片类型根据实际调整,比如 image/png .build() // 构建 mutation 请求 val mutation = UploadImageMutation(upload) // 发送请求并获取响应 val response = apolloClient.mutation(mutation).execute() if (response.hasErrors()) { // 打印错误信息 response.errors?.forEach { error -> Log.e("UploadError", error.message ?: "未知错误") } null } else { response.data } } catch (e: Exception) { Log.e("UploadException", e.message ?: "上传失败") null } }
调用上传函数
在协程作用域中调用上传函数(比如 ViewModel 或 Activity 的协程里):
// 示例:假设已获取到本地图片文件 val targetImageFile = File("/storage/emulated/0/Pictures/test.jpg") // 在 IO 线程执行上传 CoroutineScope(Dispatchers.IO).launch { val uploadResult = uploadImage(targetImageFile) if (uploadResult != null) { Log.d("UploadSuccess", "图片URL: ${uploadResult.uploadImage?.url}") // 这里可以更新UI,通知用户上传成功 } else { Log.d("UploadFailed", "图片上传失败") } }
4. 服务器端配置提示
如果上传仍失败,大概率是服务器未正确配置上传支持。以 Node.js + Express 为例,需使用 graphql-upload 库处理 multipart 请求:
const { ApolloServer } = require('@apollo/server'); const { expressMiddleware } = require('@apollo/server/express4'); const { createUploadMiddleware } = require('graphql-upload'); const express = require('express'); const cors = require('cors'); const app = express(); app.use(cors()); // 添加上传中间件 app.use(createUploadMiddleware()); // 定义 Schema const typeDefs = ` scalar Upload type UploadResult { id: ID! url: String! message: String! } type Mutation { uploadImage(file: Upload!): UploadResult! } `; // 定义解析器 const resolvers = { Mutation: { uploadImage: async (_, { file }) => { const { createReadStream, filename } = await file; // 这里实现文件保存逻辑(比如存本地或云存储) const stream = createReadStream(); // 省略保存代码,直接返回模拟结果 return { id: "img_123", url: `https://你的服务器域名/images/${filename}`, message: "上传成功" }; } } }; // 启动服务器 const startServer = async () => { const server = new ApolloServer({ typeDefs, resolvers }); await server.start(); app.use('/graphql', expressMiddleware(server)); app.listen(4000, () => console.log('服务器运行在 http://localhost:4000/graphql')); }; startServer();
内容的提问来源于stack exchange,提问作者Shahriar
相关产品推荐
相关产品推荐

