跳到主要内容

GQLEndpoint

GQLEndpoints 用于基于 GraphQL 的协议。

继承

GQLEndpoint 继承自 Endpoint

用法​

实时编辑器
import { UserResource } from './resources';

export default function ProfileEdit({ id }: { id: number }) {
  const { user } = useSuspense(UserResource.get, { id });

  const controller = useController();
  const handleChange = ({ currentTarget: { value: name } }) =>
    controller.fetch(UserResource.update, { id, name });

  return (
    <TextInput
      label="Name"
      value={user.name}
      onChange={handleChange}
    />
  );
}
结果
Store▶

query(gql, schema)​

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

const gql = new GQLEndpoint('/');

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

getUser({ name: 'bob' });

mutate(gql, schema)​

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

const gql = new GQLEndpoint('/');

export const updateUser = gql.mutate(
(v: Partial<User>) => `query updateUser($user: User!) {
user(name: $user) {
id
name
email
}
}`,
{ user: User },
);

updateUser({ id: '5', name: 'bob', email: '[email protected]' });

获取的生命周期​

GQLEndpoint 在 Endpoint 的基础上,为其提供的 fetch 方法增加了定制能力。

  1. 准备 fetch
    1. url
    2. getRequestInit()
  2. 执行 fetch
    1. fetchResponse()
    2. parseResponse()
    3. process()
fetch implementation for GQLEndpoint
async function fetch(variables) {
return this.fetchResponse(
this.url,
this.getRequestInit(variables),
).then(res => this.process(res, variables));
}

准备 Fetch​

成员同时也是选项(构造函数的第二个参数)。虽然都不是必需的,但前几个有默认值。

url: string​

GraphQL 对所有操作使用同一个 url。

getRequestInit(body): RequestInit​

准备 fetch 中使用的 RequestInit。它会被传给 fetchResponse

getQuery(variables): string​

准备查询语句,作为 body 负载的一部分发送。

getHeaders(headers: HeadersInit): HeadersInit​

由 getRequestInit 调用,用于确定 HTTP 请求头

这通常可用于认证

注意

不要在这里使用 hook。

处理 fetch​

fetchResponse(input, init): Promise​

执行 fetch 调用

parseResponse(response): Promise​

接收 Response,并通过 .text() 或 .json() 进行解析

process(value, ...args): any​

对解析后的结果执行任意转换。默认为恒等函数。

Endpoint 生命周期​

schema: Schema​

声明式地定义如何处理响应

  • 在何处预期出现 Entity
  • 用于反序列化字段的函数

不提供此选项意味着不会提取任何 Entity。

import { GQLEntity, GQLEndpoint } from '@data-client/graphql';
const gql = new GQLEndpoint('https://nosy-baritone.glitch.me');

class User extends GQLEntity {
username = '';
}

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

dataExpiryLength?: number​

为所获取资源自定义数据缓存的生命周期。会覆盖 NetworkManager 中设置的值。

进一步了解过期时间

errorExpiryLength?: number​

为所获取资源自定义错误的生命周期。会覆盖 NetworkManager 中设置的值。

errorPolicy?: (error: any) => 'soft' | undefined​

'soft' 会在出错时使用过时数据(如果存在);值为 undefined 或不提供此选项则会导致报错。

进一步了解 errorPolicy

errorPolicy(error) {
return error.status >= 500 ? 'soft' : undefined;
}

invalidIfStale: boolean​

表示过时数据应被视为不可用,因此不会从缓存中返回。这意味着即使数据已存在于缓存中,只要它过时了,useSuspense() 就会挂起。

pollFrequency: number​

轮询的频率,单位为毫秒。需要配合 useSubscription() 或 useLive() 使用才会生效。

getOptimisticResponse: (snap, ...args) => fakePayload​

提供此函数后,使用该 endpoint 的任何获取都会表现得如同此函数返回的 fakePayload 是一次成功的网络响应。当实际获取完成时(无论失败还是成功),乐观更新都会被实际的网络响应替换。

extend(options): Endpoint​

可用于进一步定制 endpoint 的定义

const gql = new GQLEndpoint('https://nosy-baritone.glitch.me');

const authGQL = gql.extend({
getHeaders(headers: HeadersInit): HeadersInit {
return {
...headers,
'Access-Token': getAuth(),
};
},
});