以下是如何在GRAPHQL中上传文件...既简单又困难。
不用多久就会意识到_在GraphQL中上传文件是一大痛点_。文件上传一般都很复杂,即使在REST API中也是如此。经常有人断然建议在上传文件时考虑换回REST,但_真的有那么糟糕吗_我已经研究了一段时间了。_这里介绍一下如何用GraphQL上传文件_。
对于GraphQL文件上传来说,**最可行的选择似乎是Jayden Seric的多部分请求扩展,如果你喜欢维护一个单一的GraphQL端点,并通过GraphQL突变传入你的文件。或者你可以维护一个单独的端点来POST上传到(通常用REST HTTP方法实现)。第三种是在您的突变中使用第三方外部存储,如S3 URLS。
在GraphQL中上传文件并不是那么普遍。这些也许是因为没有官方支持,而且GraphQL文档对文件上传奇怪地保持沉默。
通常建议,除了你的GraphQL之外,简单地创建和端点(通常在REST中)来发布文件,通常就足够了。但如果你只想维护一个GraphQL端点呢?
让我们踢这是通过首先介绍REST是如何做文件上传,然后轻松进入使用这个后台上传文件到GraphQL服务器。
Uploading Files in REST
一个【REST胜过GraphQL的关键领域】(https://leapgraph.com/why-gra...。REST利用HTTP来处理图片等文件上传。
一个典型的REST图片上传看起来如下。
`POST /images HTTP/1.1
Authentication: Bearer < token >
Host: localhost:4000
Content-Type: image/jpeg
Content-Length: 1254
raw image content`
基于URL的上传是以同样的方式使用application/json
请求来处理的。
`POST /images HTTP/1.1
Host: localhost:4000
Content-Type: image/jpeg
Content-Length: 244
{
"image_url" : "https://cdn.example.org/image.png"
}`
在REST中上传文件通常需要三种不同的方法。
直接上传文件
这只是通过名称引用文件来上传。JSON数据通常与图片一起发送,但它可以被分割成一个不同的请求。
使用文件元数据上传
这种方法通常与多部分上传有关。文件被MultipartBoundry
边界分隔符分割。多部分上传通常被认为是俗气的黑客,因为请求往往很快就会变得很大很乱(而且字段也会被分割)。
从外部URL上传
这是在上面第二个第二个请求中使用https://cdn.example.org/image.png
做的。
一个多部分的上传会看起来像这样。
`POST /images HTTP/1.1
Host: localhost:4000
Authentication: Bearer < token >
Content-Type: multipart/form-data; boundary=MultipartBoundry
Accept-Encoding: gzip, deflate
--MultipartBoundry
Content-Disposition: form-data; name="image"; filename="458485515151024_454541324960893_3451511151369966555525_n.jpg"
Content-Type: image/jpeg
raw image content
--MultipartBoundry
Content-Disposition: form-data; name="imageJsonData"
Content-Type: application/json
--MultipartBoundry--`
How To Upload Files in GraphQL
在GraphQL中上传文件并非易事。首先GraphQL不像REST那样利用HTTP方法。然后是单一的端点。
让我们看看GraphQL中上传文件的一些方法。
Uploading with GraphQL Mutations
GraphQL不允许在突变中使用原始文件。它只处理序列化数据。
有一些变通的方法可以解决这个问题。其中最有用的是
Uploading via REST Endpoints in GraphQL Mutations
在graphql突变里面,可以使用单独的REST API在graphql中上传文件。
使用这种方法又增加了一层复杂性。文件必须先上传到REST,然后在GraphQL突变中传递结果的上传URL。这通常是一个缓慢的过程,而且现在有两个服务器需要管理。
REST API使用之前概述的方法来上传文件。
Uploading Files as Base64 Encoded Strings
Base64
编码的字符串可以通过GraphQL突变。
编码后的字符串通常比其二进制对应物大,但有三分之一。
字符串的编码也可以很快地成为资源密集型的,而且它有时充满了错误。
Uploading file using External URLs (such as AWS S3)
另一种上传文件到GrapQL的方式是使用S3。一旦一个文件上传到S3并生成一个文件url id,该url就可以在Graph Mutation中使用,将文件存储在GraphQL服务器中。
Uploading Files using apollo-upload-server
apollo-upload-server
是一个库,它允许你在graphql突变中上传文件,而不需要创建一个REST端点来处理这些上传。
它使用一个名为multipart request spec的扩展来处理文件传输。
然后,要上传的文件可以在GraphQL突变中的任何地方使用如下变量进行嵌套。
{
query: `
mutation($image: Upload!) {
uploadImage(image: $image) {
id
}
}
`,
variables: {
image: Image // image.jpg
}
}
该文件就像其他突变参数一样被添加。
Apollo Upload是用apollo-upload-server
npm包安装的,在Apollo Server和Express中实现如下。
`import { apolloUploadExpress } from 'apollo-upload-server'
...
app.use(
'/graphql',
bodyParser.json(),
apolloUploadExpress(/* Options */),
graphqlExpress(/* … */)`
这些选项用于设置最大文件(maxFiles
)、文件上传大小(maxFileSize
)和字段大小(maxFieldSize
)。
文件上传标量被添加到类型和解析器中,具体如下:
``import { makeExecutableSchema } from 'graphql-tools'
import { apolloUploadExpress, GraphQLUpload } from 'apollo-upload-server'
-*
const schema = makeExecutableSchema({
typeDefs: `scalar Upload`,
resolvers: { Upload: GraphQLUpload }
})``
用多部分请求滚动你自己的上传者。
另一种选择是在你的多部分请求上滚动。这将代替使用apollo-upload-server
(和apollo-upload-client
),尽管这两种方法有很多相似之处,例如它们利用了GraphQL-request。
Jayden Seric多部分扩展与滚动自己的方法相比也有一些优势,例如解析器中的文件上传流和中止文件上传的能力。
要滚动您自己的上传器,您将使用GraphQL-request发送任意数据的能力,而不是常规的POST-request--这就是您发送多部分请求的方式。
对于多部分请求,GraphQL需要一个query
字段。
在我们的GraphQL服务器上,多部分请求被读入一个request
对象,然后被传递到解析器上下文中。
客户端也需要一个代码NetworkInterface来处理多部分请求。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。