You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 17:57:14