- NPM
- Yarn
- pnpm
- esm.sh
yarn add @data-client/graphql
npm install --save @data-client/graphql
pnpm add @data-client/graphql
<script type="module">
import * from 'https://esm.sh/@data-client/graphql';
</script>
Define el Endpoint y el Schema
export const gql = new GQLEndpoint('https://nosy-baritone.glitch.me');
export default gql;
- TypeScript
- JavaScript
import { GQLEntity } from '@data-client/graphql';
export default class User extends GQLEntity {
name: string | null = null;
email = '';
age = 0;
}
import { GQLEntity } from '@data-client/graphql';
export default class User extends GQLEntity {}
Las Entity son inmutables. Usa readonly en TypeScript para imponerlo.
Usar GQLEntities no es obligatorio, pero es importante para lograr la consistencia de los datos.
Consulta el grafo
- Single
- List
import { useSuspense } from '@data-client/react';
import User from 'schema/User';
import gql from 'schema/endpoint';
export const userDetail = gql.query(
(v: { name: string }) => `query UserDetail($name: String!) {
user(name: $name) {
id
name
email
}
}`,
{ user: User },
);
export default function UserDetail({ name }: { name: string }) {
const { user } = useSuspense(userDetail, { name });
return (
<article>
<h2>{user.name}</h2>
<div>{user.email}</div>
</article>
);
}
import { useSuspense } from '@data-client/react';
import User from 'schema/User';
import gql from 'schema/endpoint';
const userList = gql.query(
`{
users {
id
name
email
}
}`,
{ users: [User] },
);
export default function UserList() {
const { users } = useSuspense(userList, {});
return (
<section>
{users.map(user => (
<UserSummary key={user.pk()} user={user} />
))}
</section>
);
}
useSuspense() garantiza el acceso a datos con la frescura suficiente. Esto significa que puede realizar llamadas de red y que puede suspender hasta que el fetch se complete. Los cambios de parámetros darán acceso a los datos adecuados, lo que a veces también provoca nuevas llamadas de red y/o suspensiones.
- Los fetches se controlan de forma centralizada y, por tanto, se deduplican automáticamente
- Los datos están centralizados y normalizados, lo que garantiza la consistencia entre usos, incluso con distintos endpoints.
- (Por ejemplo: navegar a una página de detalle de un solo elemento desde una vista de lista mostrará al instante los mismos datos que la lista sin necesidad de volver a hacer el fetch.)
Demo de SWAPI
import { useSuspense } from '@data-client/react'; import { GQLEndpoint, GQLEntity } from '@data-client/graphql'; const gql = new GQLEndpoint( 'https://swapi-graphql.netlify.app/graphql', ); class Person extends GQLEntity { readonly id: string = ''; readonly name: string = ''; readonly height: string = ''; } const PageInfo = { hasNextPage: false, startCursor: '', endCursor: '', }; const allPeople = gql.query( (v: { first?: number; after?: string }) => ` query People($first: Int, $after:String) { allPeople(first: $first, after:$after) { people{ id,name,height }, pageInfo { hasNextPage, startCursor, endCursor } } } `, { allPeople: { people: [Person], pageInfo: PageInfo } }, ); function StarPeople() { const { people, pageInfo } = useSuspense(allPeople, { first: 5, }).allPeople; return ( <div> {people.map(person => ( <div key={person.id}> name: {person.name} height: {person.height} </div> ))} </div> ); } render(<StarPeople />);
Muta el grafo
Usamos SWAPI como ejemplo, ya que ofrece mutaciones.
import { useController } from '@data-client/react';
import { GQLEndpoint, GQLEntity } from '@data-client/graphql';
const gql = new GQLEndpoint(
'https://swapi-graphql.netlify.app/graphql',
);
class Review extends GQLEntity {
readonly stars: number = 0;
readonly commentary: string = '';
}
const createReview = gql.mutation(
(v: {
ep: string;
review: { stars: number; commentary: string };
}) => `mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
createReview(episode: $ep, review: $review) {
stars
commentary
}
}`,
{ createReview: Review },
);
export default function NewReviewForm() {
const ctrl = useController();
return (
<Form onSubmit={variables => ctrl.fetch(createReview, variables)}>
<FormField name="ep" />
<FormField name="review" type="compound" />
</Form>
);
}
El primer argumento de GQLEndpoint.query o GQLEndpoint.mutate es la cadena de la consulta o una función que devuelve la cadena de la consulta. La principal ventaja de usar la segunda opción es imponer los tipos de los argumentos de la función.
Demo de combinación con REST
Explora el ejemplo github-app