美文网首页
GraphQL观感

GraphQL观感

作者: wu_sphinx | 来源:发表于2019-12-03 11:37 被阅读0次

    GraphQL是什么

    GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。

    读完这句也没有获得很明确的信息,为便于理解,我们以Django为例,两张表的定义如下所示

    class Category(models.Model):
        name = models.CharField(max_length=100)
    
        def __str__(self):
            return self.name
    
    class Ingredient(models.Model):
        name = models.CharField(max_length=100)
        notes = models.TextField()
        category = models.ForeignKey(
            Category, related_name='ingredients', on_delete=models.CASCADE)
    
        def __str__(self):
            return self.name
    

    如果我们按照传统RESTFul API的写法,大抵可以写成下面这样子

    class IngredientSerializer(serializers.HyperlinkedModelSerializer):
        class Meta:
            model = Ingredient
            fields = ['name', 'notes', 'category']
    
    
    class IngredientViewSet(viewsets.ModelViewSet):
        """
        API endpoint that allows users to be viewed or edited.
        """
        queryset = Ingredient.objects.all()
        serializer_class = IngredientSerializer
    

    不过在我有限的后端开发经历过程中,曾经遇到这种情况,跟手机端的同学对接接口,有的接口需要Ingredient的全部字段,而有的接口又只需Ingredientnotes字段,这个带来的麻烦在于

    • 一个接口,数据字段给多了,可以做到通用,但是难免浪费流量
    • 接口分开,代码冗余,毕竟除了返回字段不一样,查询过程是一样的

    姑且不看GraphQL是如何解决这个问题的,先来看一下结果

    ➜  ~ curl -iX POST http://raspberrypi.local:8000/graphql -H 'content-type: application/json' -d '{"query": "{allIngredients {id name category{name}}}"}'
    HTTP/1.1 200 OK
    Date: Tue, 03 Dec 2019 03:04:18 GMT
    Server: WSGIServer/0.2 CPython/3.7.4
    Content-Type: application/json
    Vary: Cookie
    X-Frame-Options: SAMEORIGIN
    Content-Length: 242
    Set-Cookie:  csrftoken=F0zhAsDXcAxO78m2VXL6Hj7d3wnsLG8xPPurzEVWQJk5JesB5pwij7mQrNnMslsk; expires=Tue, 01 Dec 2020 03:04:18 GMT; Max-Age=31449600; Path=/; SameSite=Lax
    
    {"data":{"allIngredients":[{"id":"1","name":"Eggs","category":{"name":"Dairy"}},{"id":"2","name":"Milk","category":{"name":"Dairy"}},{"id":"3","name":"Beef","category":{"name":"Meat"}},{"id":"4","name":"Chicken","category":{"name":"Meat"}}]}}
    

    若我只要notes字段,又该如何?

    curl -iX POST http://raspberrypi.local:8000/graphql -H 'content-type: application/json' -d '{"query": "{allIngredients {notes}}"}'
    HTTP/1.1 200 OK
    Date: Tue, 03 Dec 2019 03:06:09 GMT
    Server: WSGIServer/0.2 CPython/3.7.4
    Content-Type: application/json
    Vary: Cookie
    X-Frame-Options: SAMEORIGIN
    Content-Length: 181
    Set-Cookie:  csrftoken=YGb6Eyb31DjBs4YUFfcuz3bAOre9p1oyfKy0nwxmM4uHsOrECvV0aL9IG2tD6fog; expires=Tue, 01 Dec 2020 03:06:09 GMT; Max-Age=31449600; Path=/; SameSite=Lax
    
    {"data":{"allIngredients":[{"notes":"Good old eggs"},{"notes":"Comes from a cow"},{"notes":"Much like milk, this comes from a cow"},{"notes":"Definitely doesn't come from a cow"}]}}
    

    好像有一种魔力,我需要什么格式,接口就给我什么格式的数据,且看两次的查询参数

    {"query": "{allIngredients {id name category{name}}}"}
    

    {"query": "{allIngredients {notes}}"}
    

    很明显,返回的数据结构跟查询数据结构颇为相似,而且是同一个接口,这是GraphQL的“魔法”,当然,数据库查询这一块无论用哪种方法都是一样的,在数据返回这块,GraphQL隐藏了复杂的后台处理过程,让数据获取方根据自己的需求,在GraphQL的规则之下,获取自己想要的数据,不多不少,刚刚好,这是初试GraphQL后我的实际使用观感

    优/缺点

    • GraphQL在接口数据的运用上洽到好处
    • 后端的工作量初看是增加了,不过好在GraphQLRESTFul并非水火不融,二者可共存,可小范围试用
    • 传统方法前端几乎可以无脑调用接口展示数据,使用GraphQL需要前端知悉后端逻辑,这很fullstack
    • GraphQL工具链不算很完整,目前还在发展中,虽有不少大公司在尝鲜,但少有生产实践资料与经验,前景未明

    数据库这一层所做之事均是一样的,数据查询这块做文章能带来多大的收益?不过前后端沟通成本也是一个问题,我能想到的是:若是全栈开发这么写倒是挺不错的

    GraphQL可持续关注,且听下回分解

    参考

    相关文章

      网友评论

          本文标题:GraphQL观感

          本文链接:https://www.haomeiwen.com/subject/qdqcgctx.html