Help us understand the problem. What is going on with this article?

graphql clientはApolloよりfetchでやった方がいいのではないかという件

リポジトリ

https://github.com/gqlkit-repos/gqlkit-store
graphql client storeプラグインです。
これを、各フレームワークのcontextに突っ込んでやろうという魂胆
reduxはreact、vuexはvueという感じですが
クロスフレームワークでかつgraphqlの為の
client&storeというのを作ってみました。
nuxt.jsでは検証済

resolverファーストアーキテクチャのgraphql client設計

.
├── index.js
└── resolvers
    ├── Mutation
    │   ├── createStaff.js
    │   └── deleteStaff.js
    ├── Query
    │   └── staffs.js
    ├── cache.js
    └── client.js

たったのこれだけ
と言いたいところですが
これを例えば、nuxtで使うなら、nuxtのpluginsディレクトリに突っ込むので
一見、まぁまぁな規模感あるように見えます。

というか、そもそもなのですが
クライアント側のvuexとかreduxだとかのストアが抱えている課題って
もうストアはストアで別個のフレームワークと捉えて設計した方が良いレベルではないかと思うので
これはなんか正解路線なのでは?と思っています。

ちなみにQueryとMutation以下のjsファイルはデモ用のファイルです。

queryのコードの見た目も、mutationのコードの見た目もほぼ同じ

上のディレクトリツリーのstaffs.jsはこんな感じ

staffs.js
import client from '../client'
import cache from '../cache'
import gql from 'graphql-tag'

export const demand = gql`
    query {
        staffs {
            id
            name
            age
            sex
        }
    }
`

export default async variables => {
    let re
    if (!cache.has('staffs').value()) {
        const { staffs } = await client.req(demand)
        cache.set('staffs', staffs).write()
        re = staffs
    } else {
        re = cache.get('staffs').value()
    }

    return re
}

mutationにあたるcreateStaff.jsはこんな感じ
mutationはrefetchしたいモジュールファイルをrefetchという名前で読み込みます。
そんでもってqueryでもmutationでも
クライアントツールはclient.req(demand, variables)(variablesが必要ない場合は省略)

createStaff.js
import client from '../client'
import cache from '../cache'
import gql from 'graphql-tag'
import refetch from "../Query/staffs";

export const demand = gql`
    mutation($name: String!, $age: Int!, $sex: String!) {
        createStaff(name: $name, age: $age, sex: $sex) {
            id
            name
            age
            sex
        }
    }
`

export default async variables => {
    const res = await client.req(demand, variables)
    const staff = res.createStaff
    const staffs = cache.get('staffs').value()
    staffs.push(staff)
    cache.set('staffs', staffs).write()

    return refetch()
}

クライアントツールは21行のコードでqueryもmutationもOK!

fetchで書くとこんなシンプルになるとは正直、驚きました。
ただ、今後subscription導入のことも考えると
もうちょっと大きいファイルになる可能性はあります。
まだ、subscriptionは未経験なので。。。

client.js
const GQLKIT_SERVER_END_POINT = process.env.GQLKIT_SERVER_END_POINT || 'http://localhost:4000/query'
const method = 'POST'
const headers = {
    'Content-Type': 'application/json',
    Accept: 'application/json'
}

export default {
    async req(demand, variables) {
        const res = await fetch(GQLKIT_SERVER_END_POINT, {
            method,
            headers,
            body: JSON.stringify({
                query: demand.loc.source.body,
                variables
            })
        })
        const { data } = await res.json()
        return data
    }
}


キャッシュはどうするか?

キャッシュは完全切り分けの方針です。
Apolloのapiはキャッシュと密結合ですが
resolverファーストなgraphql clientアーキテクチャでは
キャッシュは完全別扱いにして
好きなin memory dbを使えば良いという方針で考えます。
resolverを書いて解決すれば良いじゃないか!という方針です。

僕は今のところlowdbを使っています。
ここはお好みで好きなもの使ってよしです。

cache.js
import low from 'lowdb'
import Memory from 'lowdb/adapters/Memory'

const cache = low(new Memory())

cache.defaults({}).write()

export default cache

まとめ

apolloがなぜ、あれほどまでに複雑なアーキテクチャを取っているのか
僕の知らない何らかの理由でああなっている可能性も大なので

これがベストアンサーだなんて到底言い切る事はできないです。
これはあくまで、1アイデアというものです。

あと、jsのオブジェクトをgormっぽい書き方で読み書き出来るような
ツールをご存知の方おられましたら教えて頂けると嬉しいです。

サーバーとクライアントで違うノウハウというのを最小限に抑えたい
ということで
graphqlサーバーのアーキテクチャを真似たプラグインを作ってみたという話でした。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした