普通的 REST API 可能会让您以不同的格式请求相同的数据,并使用不同的Accept
标头,例如application/json
, or text/html
, or a text/csv
格式化的响应。
但是,如果您使用 GraphQL,则 JSON 似乎是唯一可接受的返回内容类型。但是,我需要我的 API 能够返回 CSV 数据,以供无法理解 JSON 的不太复杂的客户端使用。
如果给定一个 GraphQL 端点返回 CSV 数据是否有意义Accept: text/csv
标头?如果没有,是否有更好的练习方法来做到这一点?
这更多的是一个概念性问题,但我专门使用Graphene https://graphene-python.org/来实现我的 API。它是否提供任何处理自定义内容类型的机制?
是的,你可以,但它不是内置的,你必须覆盖一些东西。这更像是一种解决方法。
执行以下步骤,您将获得 csv 输出:
-
Add csv = graphene.String()
根据您的疑问并将其解决为您想要的任何内容。
-
创建一个新类继承GraphQLView
-
覆盖dispatch
函数看起来像这样:
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
-
导入所有必要的模块
-
替换默认值GraphQLView
在你的urls.py
文件与您的新视图类。
现在,如果您在 GraphQL 查询中包含“csv”,它将返回原始 csv 数据,然后您可以将数据保存到前端的 csv 文件中。示例查询如下:
query{
items{
id
name
price
category{
name
}
}
csv
}
请记住,这是一种获取 csv 格式的原始数据的方法,您必须保存它。您可以使用以下代码在 JavaScript 中执行此操作:
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 数据,因此不会丢失任何数据。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)