使用 GraphQL 机器,但返回 CSV [英] Using GraphQL machinery, but return CSV
问题描述
普通的 REST API 可能让您以不同的格式请求相同的数据,使用不同的 Accept
标头,例如application/json
,或 text/html
,或 text/csv
格式的响应.
A normal REST API might let you request the same data in different formats, with a different Accept
header, e.g. application/json
, or text/html
, or a text/csv
formatted response.
但是,如果您使用的是 GraphQL,那么 JSON 似乎是唯一可接受的返回内容类型.但是,我需要我的 API 能够返回 CSV 数据以供不理解 JSON 的不太复杂的客户端使用.
However, if you're using GraphQL, it seems that JSON is the only acceptable return content type. However, I need my API to be able to return CSV data for consumption by less sophisticated clients that won't understand JSON.
如果给定 Accept: text/csv
标头,GraphQL 端点返回 CSV 数据是否有意义?如果没有,是否有更好的实践方法来做到这一点?
Does it make sense for a GraphQL endpoint to return CSV data if given an Accept: text/csv
header? If not, is there a better practise way to do this?
这更像是一个概念性问题,但我专门使用 Graphene 来实现我的 API.它是否提供任何机制来处理自定义内容类型?
This is more of a conceptual question, but I'm specifically using Graphene to implement my API. Does it provide any mechanism for handling custom content types?
推荐答案
是的,你可以,但它不是内置的,你必须覆盖一些东西.这更像是一种解决方法.
Yes, you can, but it's not built in and you have to override some things. It's more like a work around.
采取这些步骤,您将获得 csv 输出:
Take these steps and you will get csv output:
将
csv = graphene.String()
添加到您的查询中并将其解析为您想要的任何内容.
Add
csv = graphene.String()
to your queries and resolve it to whatever you want.
创建一个继承GraphQLView
覆盖 dispatch
函数看起来像这样:
Override dispatch
function to look like this:
def dispatch(self, request, *args, **kwargs):
response = super(CustomGraphqlView, self).dispatch(request, *args, **kwargs)
try:
data = json.loads(response.content.decode('utf-8'))
if 'csv' in data['data']:
data['data'].pop('csv')
if len(list(data['data'].keys())) == 1:
model = list(data['data'].keys())[0]
else:
raise GraphQLError("can not export to csv")
data = pd.json_normalize(data['data'][model])
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="output.csv"'
writer = csv.writer(response)
writer.writerow(data.columns)
for value in data.values:
writer.writerow(value)
except GraphQLError as e:
raise e
except Exception:
pass
return response
导入所有必要的模块
Import all necessary modules
用新的视图类替换 urls.py
文件中的默认 GraphQLView
.
Replace the default GraphQLView
in your urls.py
file with your new view class.
现在,如果您包含csv"在您的 GraphQL 查询中,它将返回原始 csv 数据,然后您可以将数据保存到前端的 csv 文件中.示例查询类似于:
Now if you include "csv" in your GraphQL query, it will return raw csv data and then you can save the data into a csv file in your front-end. A sample query is like:
query{
items{
id
name
price
category{
name
}
}
csv
}
请记住,这是一种以csv格式获取原始数据的方法,您必须保存它.您可以使用以下代码在 JavaScript 中执行此操作:
Remember that it is a way to get raw data in csv format and you have to save it. You can do that in JavaScript with the following code:
req.then(data => {
let element = document.createElement('a');
element.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(data.data));
element.setAttribute('download', 'output.csv');
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
})
这种方法将 JSON 数据展平,因此不会丢失任何数据.
This approach flattens the JSON data so no data is lost.
这篇关于使用 GraphQL 机器,但返回 CSV的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!