GraphQL

與 RESTful、GRPC類似,均為 http 上層的後端與前端溝通方式

Server 用法

const typeDefs = gql`
  """
  使用者
  """
  type User {
    "識別碼"
    id: ID
    "名字"
    name: String
    "年齡"
    age: Int
    "朋友"
    friends(a: Int): [User]
  }

  type Query {
    hello: String
    "取得當下使用者"
    me: User
    "取得所有使用者"
    users: [User]
  }

  type Mutation {
    "新增使用者"
    addUser(id: ID, name: String!, age: Int): User
  }
`;

const resolvers = {
  Query: {
    hello: () => "world",
    me: () => users[0],
    users: () => users,
  },
  Mutation: {
    addUser: (root, args, context) => {
      const { id, name, age } = args;
      // 新增 post
      users.push({
        id,
        name,
        age,
      });
      return users[3];
    },
  },
  User: {
    friends: (parent, args, context) => {
      const { friendIds } = parent;
      return users.filter((user) => friendIds.includes(user.id));
    },
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: () => {
    return {a: ""}
  }
});

typeDefs 用來定義 type,內建有 query, mutation, subscribe 三種 type。

resolvers 用來處理當接收到 query 或 mutation 或 subscribe 時要做的對應處理,resolvers 包含三個預設參數 (parent, args, context)

context 讓 server 可以傳遞訊息讓 resolvers 第三個參數接收

Query

React 範例:

記得要寫在 ApolloProvider 裡面的 component 內,如果直接在 ApolloProvider 同個 component 使用 useQuery 會無法

Fragment

把 client 寫 query 時的結構拆出來,讓他可以重複使用

Mutation

example:

Subscription

Server: https://www.apollographql.com/docs/apollo-server/data/subscriptions/

React: https://www.apollographql.com/docs/react/data/subscriptions/

typeDefs

  1. 回傳 array 就用 [] 把其他 type 包住

  2. 直接在名稱上方可寫註解

  3. ! 代表必填參數 post(id: ID!): Post

預設 types

自定義 scalar type

也是寫在 resolver 然後使用 new GraphQLScalarType()

https://ithelp.ithome.com.tw/articles/10206366

resolvers

parent: 使用參數可以存取client 下指令時的function 上一層資料,但只能存取最多上一層,無法使用 parent.parent

args: 可存取使用者在 client 下指令時 function 後的參數

context: 存取傳進 Apollo Server 初始化時 context 的資料

還有第四個參數叫 info 但因為不常用,可以查看:

https://www.prisma.io/blog/graphql-server-basics-demystifying-the-info-argument-in-graphql-resolvers-6f26249f613a

Subscribe

1.很重要一點是必須要把 client 端 ws link 與 http link 分開,不然會沒有資料回傳給 subscribe

2.server 的 resolver 一定要放以下格式,包含 Subscription, subscribe 與 asyncIterator

3. server resolver mutation 裡面記得要放

完整範例:https://gist.github.com/EasonWang01/4c1a803b5680bfc76b5c71756ebc6df4

Authorization

https://ithelp.ithome.com.tw/articles/10205426

其他工具

GraphQL 後端專用的 ORM,方便資料庫溝通

Graphql-tag

parse gql string to AST ( 在 apollo-boost 內也有 )

@apollo/client

取代了 react-apollo, apollo-boost 等,將一些 client 要用到的在 Apollo Client 3.0 都包含了進去。

https://www.apollographql.com/docs/react/migrating/apollo-client-3-migration/

React hook

常見問題

1.執行 query 後出現 unexpect token <

通常是 endpoint 後的 url 路徑不對

https://github.com/graphql-boilerplates/node-graphql-server/issues/274#issuecomment-381910134

Last updated

Was this helpful?