使用 Apollo 客户端将文件上传到 GraphQL
Uploading a file to GraphQL using Apollo Client
我目前正在尝试将文件(来自 RNCamera 的图像)从 React Native android 应用程序上传到 GraphQL 后端。但是后台总是returnsstatus code 400.
到目前为止,我已经尝试使用另一个只需要一个字符串(而不是 $file 参数)的查询并且有效。所以 Apollo Client 似乎设置正确。我也尝试过使用 curl 将文件发送到后端。这也很好用。
import { API_URL } from 'src/utils/config';
import { ApolloClient, InMemoryCache, ApolloLink, gql } from '@apollo/client';
import { createUploadLink } from 'apollo-upload-client';
import { UPLOAD_PICTURE } from 'src/utils/query';
var RNFS = require('react-native-fs');
// Instantiate required constructor fields
const cache = new InMemoryCache();
const link = ApolloLink.from([
createUploadLink({
uri: API_URL
})
]);
const client = new ApolloClient({
// Provide required constructor fields
cache: cache,
link: link
});
执行突变:
// read the image that was saved as a file
const file = {
file: await RNFS.readFile(action.picture.uri, 'base64')
};
// send the file to the backend
client
.mutate({
mutation: gql(UPLOAD_PICTURE),
variables: file
})
来自src/utils/query:
export const UPLOAD_PICTURE = `
mutation ($file: Upload!){
uploadFile(file: $file)
}
`;
后端的 GraphQL 模式:
type File {
uri: String!
filename: String!
mimetype: String!
encoding: String!
}
//...
type Mutation {
//...
uploadFile(file: Upload!): File
}
我找到了解决问题的方法。 file
必须是 ReactNativeFile
类型(更多信息 here)。代码现在看起来像这样:
...
const file = new ReactNativeFile({
uri: action.picture.uri,
name: 'name.jpg',
type: 'image/jpeg'
});
...
还有一个 bug 与 React Native 0.62+ 混淆了多形式请求的配置。可以通过在 android/app/src/debug/java/com/maxyride/app/drivers/ReactNativeFlipper.java
:
中注释掉 line 43 来修复
//builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
我目前正在尝试将文件(来自 RNCamera 的图像)从 React Native android 应用程序上传到 GraphQL 后端。但是后台总是returnsstatus code 400.
到目前为止,我已经尝试使用另一个只需要一个字符串(而不是 $file 参数)的查询并且有效。所以 Apollo Client 似乎设置正确。我也尝试过使用 curl 将文件发送到后端。这也很好用。
import { API_URL } from 'src/utils/config';
import { ApolloClient, InMemoryCache, ApolloLink, gql } from '@apollo/client';
import { createUploadLink } from 'apollo-upload-client';
import { UPLOAD_PICTURE } from 'src/utils/query';
var RNFS = require('react-native-fs');
// Instantiate required constructor fields
const cache = new InMemoryCache();
const link = ApolloLink.from([
createUploadLink({
uri: API_URL
})
]);
const client = new ApolloClient({
// Provide required constructor fields
cache: cache,
link: link
});
执行突变:
// read the image that was saved as a file
const file = {
file: await RNFS.readFile(action.picture.uri, 'base64')
};
// send the file to the backend
client
.mutate({
mutation: gql(UPLOAD_PICTURE),
variables: file
})
来自src/utils/query:
export const UPLOAD_PICTURE = `
mutation ($file: Upload!){
uploadFile(file: $file)
}
`;
后端的 GraphQL 模式:
type File {
uri: String!
filename: String!
mimetype: String!
encoding: String!
}
//...
type Mutation {
//...
uploadFile(file: Upload!): File
}
我找到了解决问题的方法。 file
必须是 ReactNativeFile
类型(更多信息 here)。代码现在看起来像这样:
...
const file = new ReactNativeFile({
uri: action.picture.uri,
name: 'name.jpg',
type: 'image/jpeg'
});
...
还有一个 bug 与 React Native 0.62+ 混淆了多形式请求的配置。可以通过在 android/app/src/debug/java/com/maxyride/app/drivers/ReactNativeFlipper.java
:
//builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));