嘿,是的,但它需要一些定制工作!
这是使用scaphold.io的方法,但您也可以将其扩展到您自己的实现!
基本上发生的事情是您将文件附加到 multipart/form-data 请求的根级别,然后从 GraphQL 变量中的输入指向请求中文件的键。下面是一些代码,展示了如何使用文件就绪网络接口改造 ApolloClient 实例,然后您可以将其馈送到 Angular2Apollo。
import { createNetworkInterface } from 'apollo-client';
// Create a file-ready ApolloClient instance.
export function makeClientApolloFileHandler() {
const graphqlUrl = `https://scaphold.io/graphql/my-app`;
const networkInterface = createNetworkInterface(graphqlUrl);
networkInterface.query = (request) => {
const formData = new FormData();
// Parse out the file and append at root level of form data.
const varDefs = request.query.definitions[0].variableDefinitions;
let vars = [];
if (varDefs && varDefs.length) {
vars = varDefs.map(def => def.variable.name.value);
}
const activeVars = vars.map(v => request.variables[v]);
const fname = find(activeVars, 'blobFieldName');
if (fname) {
const blobFieldName = fname.blobFieldName;
formData.append(blobFieldName, request.variables[blobFieldName]);
}
formData.append('query', printGraphQL(request.query));
formData.append('variables', JSON.stringify(request.variables || {}));
formData.append('operationName', JSON.stringify(request.operationName || ''));
const headers = { Accept: '*/*' };
if (localStorage.getItem('scaphold_user_token')) {
headers.Authorization = `Bearer ${localStorage.getItem('scaphold_user_token')}`;
}
return fetch(graphqlUrl, {
headers,
body: formData,
method: 'POST',
}).then(result => result.json());
};
const clientFileGraphql = new ApolloClient({
networkInterface,
initialState: {},
});
return clientFileGraphql;
}
在此函数处理请求后,您可能会拥有如下所示的 FormData(如果它是用 JSON 编码的):
{
"query": "mutation CreateFile($input:CreateFileInput) { createFile(input: $input) { ... }",
"variables": {
"input": {
"blobFieldName": "myFile",
"name": "MyFileName!"
}
},
// Note how the blobFieldName points to this key
"myFile": <Buffer of file data in multipart/form-data>
}
然后,服务器需要了解如何解释这一点,以便在有效负载中查找文件并将其与正确的对象等相关联。
希望这可以帮助!