data-client-graphql-setup

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

GraphQL Protocol Setup

GraphQL协议设置

This skill configures
@data-client/graphql
for a project. It should be applied after
data-client-setup
detects GraphQL patterns.
本技能用于为项目配置
@data-client/graphql
。应在
data-client-setup
检测到GraphQL模式后应用。

Installation

安装

Install the GraphQL package alongside the core package:
bash
undefined
与核心包一起安装GraphQL包:
bash
undefined

npm

npm

npm install @data-client/graphql
npm install @data-client/graphql

yarn

yarn

yarn add @data-client/graphql
yarn add @data-client/graphql

pnpm

pnpm

pnpm add @data-client/graphql
undefined
pnpm add @data-client/graphql
undefined

GQLEndpoint Setup

GQLEndpoint设置

Basic Configuration

基础配置

Create a file at
src/api/gql.ts
(or similar):
ts
import { GQLEndpoint } from '@data-client/graphql';

export const gql = new GQLEndpoint('/graphql');
src/api/gql.ts
(或类似路径)创建文件:
ts
import { GQLEndpoint } from '@data-client/graphql';

export const gql = new GQLEndpoint('/graphql');

Detection Checklist

检测清单

Scan the existing codebase for GraphQL patterns:
  1. GraphQL endpoint URL: Look for
    /graphql
    or custom paths
  2. Authentication: Check for auth headers in existing GraphQL client setup
  3. Custom headers: API keys, tenant IDs, etc.
  4. Error handling: GraphQL error parsing patterns
扫描现有代码库中的GraphQL模式:
  1. GraphQL端点URL:查找
    /graphql
    或自定义路径
  2. 认证:检查现有GraphQL客户端设置中的认证头
  3. 自定义头:API密钥、租户ID等
  4. 错误处理:GraphQL错误解析模式

With Authentication

带认证的配置

ts
import { GQLEndpoint } from '@data-client/graphql';

export const gql = new GQLEndpoint('/graphql', {
  getHeaders() {
    const token = localStorage.getItem('authToken');
    return {
      'Content-Type': 'application/json',
      ...(token && { Authorization: `Bearer ${token}` }),
    };
  },
});
ts
import { GQLEndpoint } from '@data-client/graphql';

export const gql = new GQLEndpoint('/graphql', {
  getHeaders() {
    const token = localStorage.getItem('authToken');
    return {
      'Content-Type': 'application/json',
      ...(token && { Authorization: `Bearer ${token}` }),
    };
  },
});

Async Authentication (token refresh)

异步认证(令牌刷新)

ts
import { GQLEndpoint } from '@data-client/graphql';

export const gql = new GQLEndpoint('/graphql', {
  async getHeaders() {
    const token = await getValidToken();
    return {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    };
  },
});
ts
import { GQLEndpoint } from '@data-client/graphql';

export const gql = new GQLEndpoint('/graphql', {
  async getHeaders() {
    const token = await getValidToken();
    return {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    };
  },
});

Custom Error Handling

自定义错误处理

ts
import { GQLEndpoint } from '@data-client/graphql';

class CustomGQLEndpoint extends GQLEndpoint {
  async fetchResponse(input: RequestInfo, init: RequestInit): Promise<any> {
    const response = await super.fetchResponse(input, init);
    
    // Handle GraphQL errors
    if (response.errors?.length) {
      const authError = response.errors.find(
        e => e.extensions?.code === 'UNAUTHENTICATED'
      );
      if (authError) {
        window.dispatchEvent(new CustomEvent('auth:expired'));
      }
    }
    
    return response;
  }
}

export const gql = new CustomGQLEndpoint('/graphql');
ts
import { GQLEndpoint } from '@data-client/graphql';

class CustomGQLEndpoint extends GQLEndpoint {
  async fetchResponse(input: RequestInfo, init: RequestInit): Promise<any> {
    const response = await super.fetchResponse(input, init);
    
    // 处理GraphQL错误
    if (response.errors?.length) {
      const authError = response.errors.find(
        e => e.extensions?.code === 'UNAUTHENTICATED'
      );
      if (authError) {
        window.dispatchEvent(new CustomEvent('auth:expired'));
      }
    }
    
    return response;
  }
}

export const gql = new CustomGQLEndpoint('/graphql');

Defining Queries and Mutations

定义查询与突变

Query Example

查询示例

ts
import { gql } from './gql';
import { User } from '../schemas/User';

export const getUser = gql.query(
  (v: { id: string }) => `
    query GetUser($id: ID!) {
      user(id: $id) {
        id
        name
        email
      }
    }
  `,
  { schema: User },
);
ts
import { gql } from './gql';
import { User } from '../schemas/User';

export const getUser = gql.query(
  (v: { id: string }) => `
    query GetUser($id: ID!) {
      user(id: $id) {
        id
        name
        email
      }
    }
  `,
  { schema: User },
);

Mutation Example

突变示例

ts
import { gql } from './gql';
import { User } from '../schemas/User';

export const updateUser = gql.mutation(
  (v: { id: string; name: string }) => `
    mutation UpdateUser($id: ID!, $name: String!) {
      updateUser(id: $id, name: $name) {
        id
        name
      }
    }
  `,
  { schema: User },
);
ts
import { gql } from './gql';
import { User } from '../schemas/User';

export const updateUser = gql.mutation(
  (v: { id: string; name: string }) => `
    mutation UpdateUser($id: ID!, $name: String!) {
      updateUser(id: $id, name: $name) {
        id
        name
      }
    }
  `,
  { schema: User },
);

With Collection

结合集合使用

ts
import { gql } from './gql';
import { User, UserCollection } from '../schemas/User';

export const listUsers = gql.query(
  () => `
    query ListUsers {
      users {
        id
        name
        email
      }
    }
  `,
  { schema: UserCollection },
);

export const createUser = gql.mutation(
  (v: { name: string; email: string }) => `
    mutation CreateUser($name: String!, $email: String!) {
      createUser(name: $name, email: $email) {
        id
        name
        email
      }
    }
  `,
  { schema: UserCollection.push },
);
ts
import { gql } from './gql';
import { User, UserCollection } from '../schemas/User';

export const listUsers = gql.query(
  () => `
    query ListUsers {
      users {
        id
        name
        email
      }
    }
  `,
  { schema: UserCollection },
);

export const createUser = gql.mutation(
  (v: { name: string; email: string }) => `
    mutation CreateUser($name: String!, $email: String!) {
      createUser(name: $name, email: $email) {
        id
        name
        email
      }
    }
  `,
  { schema: UserCollection.push },
);

Usage in Components

在组件中使用

tsx
import { useSuspense, useController } from '@data-client/react';
import { getUser, updateUser } from './api/users';

function UserProfile({ id }: { id: string }) {
  const user = useSuspense(getUser, { id });
  const ctrl = useController();

  const handleUpdate = async (name: string) => {
    await ctrl.fetch(updateUser, { id, name });
  };

  return (
    <div>
      <h1>{user.name}</h1>
      <button onClick={() => handleUpdate('New Name')}>Update</button>
    </div>
  );
}
tsx
import { useSuspense, useController } from '@data-client/react';
import { getUser, updateUser } from './api/users';

function UserProfile({ id }: { id: string }) {
  const user = useSuspense(getUser, { id });
  const ctrl = useController();

  const handleUpdate = async (name: string) => {
    await ctrl.fetch(updateUser, { id, name });
  };

  return (
    <div>
      <h1>{user.name}</h1>
      <button onClick={() => handleUpdate('New Name')}>Update</button>
    </div>
  );
}

Next Steps

后续步骤

  1. Apply skill "data-client-schema" to define Entity classes
  2. Apply skill "data-client-react" or "data-client-vue" for usage
  1. 应用技能"data-client-schema"来定义Entity类
  2. 应用技能"data-client-react"或"data-client-vue"以进行使用

References

参考资料

  • GQLEndpoint - Full GQLEndpoint API
  • GraphQL Guide - GraphQL usage guide
  • Authentication Guide - Auth patterns for GraphQL