美文网首页
Graphql前端状态管理

Graphql前端状态管理

作者: anOnion | 来源:发表于2018-12-21 20:30 被阅读0次

    Graphql & Apollo

    下图是2018年前端data layer工具的趋势图。我曾经在某一期博客提到过这张图,当时只注意了第二名的Graphql。后来发现排名第三的Apollo其实也是Graphql系列的工具,全名是apollo link state

    Graphql & Apollo

    Apollo也是使用Graphql语法管理数据,稍显不同的是它并不与后端通信,是纯粹的浏览器Local Data管理工具。Graphql在今年实现了前后端一统。

    本期默认大家已经有了一定的vue和graphql背景知识,作为延伸学习,简单介绍一下Graphql在前端操作state management的一些方法。

    vue-apollo

    VUE主要通过vue-apollo集成Graphql Client框架。用法很简单,普通的插件集成。配一下默认的link和cache就可以连接后台graphql server了。(Apollo需要在link里加stateLink,后面再谈。)

    vue-apollo-graphql
    Vue.use(VueApollo);
    
    const httpLink = new HttpLink( {uri: '/graphql'} );
    const cache = new InMemoryCache();
    // Create the apollo client
    const apolloProvider = new VueApollo({
      defaultClient: new ApolloClient({link, cache})
    });
    
    new Vue({
      ...
      apolloProvider,
      ...
    });
    

    添加Apollo Provider后,我们不再需要通过mounted/created发起请求,一切数据处理委托给Graphql,通过apollo provider即可直接绑定客户端graphql cache的数据。从某种意义上来说,graphq cache可被视为一层data layer来管理SPA的全局state。因此Graphql推出不久,影响最大的不是后端的rest api,反倒是前端的Redux。

    // in *.vue
    <template>
        <div>Get Todos from server: {{ todos }}</div>
    </template>
    
    <script>
    export default {
      apollo: {
        todos: gql`{
              todos: getTodos {
                id
                text
              }
            }
        `,
      },
       ...
    }
    <script>
    

    Memory Cache

    Memory Cache是Graphql存储数据的平台。如下所示,前端与后端交互后,Graphql客户端会在浏览器Cache里驻留response数据,然后通过这些全局缓存来管理状态。前端的graphql query默认的fetchPolicy是cache-first(顾名思义优先使用缓存,未命中则向后端请求数据,更新缓存后再渲染UI),除此之外还可以定制cache-and-networkcache-onlynetwork-only等策略。

    Store data in Graphql cache

    这里提一下,Memory Cache是通过key-value表单形式存储每一个对象。即便是数组内的对象也会被规格化存储。默认的primary key是id(或_id)和 __typename的组合键。当然也可以自定义主键

    state update
    如上图所示,点击UPDATE按钮后,触发的是某个对象的mutation操作,并未再次query State数组;但是mutation请求返回后更新了<id, __typename>主键对应的某块缓存,state数组也随之更新。
    update () {
        this.$apollo.mutate({
            mutation: gql`mutation ($id: Int, $text: String!) {
                update(id: $id, text: $text) {
                    id
                    text
                }
                }`,
            variables: {
                id: 0,
                text: `Updated`,
            },
            });
        }
    

    Apollo

    今年下半年的时候Apollo大版本更新了graphql client,推出了apollo link state,我当时没及时更近后来还折腾了一番。

    apollo client 2.0

    Apollo Client开始支持Rest api和local state的数据管理。Apollo通过新的directive(@rest、@client)指向不同的数据。如下是一个拼接了Graphql、rest和local state的查询。

    const getUser = gql`
      query getUser($id: String) {
        user(id: $id) {
          id
          name @rest(route: '/todos/name')
          cart @client
        }
      }
    `;
    

    Apollo遵循的还是Graphql的实现方式,只是把resolver放在了前端;通过直接读写cache里的数据更新state。这下就真没Redux什么事了。

    const stateLink = withClientState({
      cache,
      resolvers: {
        Mutation: {
              addTodo: (_, { id, text }, { cache }) => {
            
              const newTodo = {id, text,  __typename: 'Todo'}
              const {todos} = cache.readQuery({ query });
              todos.push(newTodo)
    
              const data = { todos };
              cache.writeData({ data });
              return newTodo;
            },
      }
      }
    });
    
    const client = new ApolloClient({
      cache,
      link: ApolloLink.from([stateLink, new HttpLink()]),
    });
    

    小结

    以上是这段时间我自己学习Apollo Graphql的一些总结。虽然接触不深,但还是可以感觉到Graphql带来的便捷。Apollo甚至给出了一套完整的前后端数据管理方案,初学者在前后端的学习成本变得更低了。相信2019年Graphql还会是前端开发的潮流,这种趋势已经不是rest、redux可阻挡的存在了。希望身边有更多小伙伴来和我一起学习,一起体验这种新的变化。

    相关文章

      网友评论

          本文标题:Graphql前端状态管理

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