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} /> ); }
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 },
);
获取的生命周期
GQLEndpoint 在 Endpoint 的基础上,为其提供的 fetch 方法增加了定制能力。
- 准备 fetch
- 执行 fetch
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。
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(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(),
};
},
});