使用 GraphQL 机器,但返回 CSV [英] Using GraphQL machinery, but return CSV

查看:31
本文介绍了使用 GraphQL 机器,但返回 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:

  1. csv = graphene.String() 添加到您的查询中并将其解析为您想要的任何内容.

  1. 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屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆