前言
GraphQL 是一种由 Facebook 发布的开源数据查询和操作语言,可以用于客户端和服务器之间的数据交互。GraphQL 具有强大的查询能力,可以精确地获取需要的数据,减少网络传输的数据量,提高数据传输的效率。在前端领域,GraphQL 的应用越来越广泛,本文将介绍 GraphQL 在前端领域的应用实践。
GraphQL 基础概念
在开始介绍 GraphQL 在前端领域的应用实践之前,我们先来了解一下 GraphQL 的基础概念。
Schema
Schema 是 GraphQL 中的核心概念,它定义了数据的类型和关系。Schema 定义了可以查询的数据类型、查询字段和关系以及可变操作。Schema 可以用 GraphQL Schema Definition Language (SDL) 或者编程语言来定义。
以下是一个简单的 Schema 示例:
// www.javascriptcn.com code example
type Query {
user(id: ID!): User
}
type User {
id: ID!
name: String!
age: Int
}这个 Schema 定义了一个 Query 类型,它有一个 user 查询字段,可以通过用户 id 获取用户信息。User 类型定义了用户的 id、name 和 age 字段。
Query
Query 是 GraphQL 的查询操作,它定义了需要获取的数据和数据结构。Query 可以嵌套,以便获取更复杂的数据结构。
以下是一个简单的 Query 示例:
query {
user(id: "1") {
id
name
age
}
}这个 Query 获取了 id 为 1 的用户信息,包括 id、name 和 age 字段。
Mutation
Mutation 是 GraphQL 的变更操作,它定义了对数据的修改、创建和删除操作。Mutation 与 Query 类似,也可以嵌套。
以下是一个简单的 Mutation 示例:
mutation {
createUser(input: { name: "Alice", age: 18 }) {
id
name
age
}
}这个 Mutation 创建了一个名为 Alice 年龄为 18 的用户,并返回用户的 id、name 和 age 字段。
Resolver
Resolver 是 GraphQL 的解析器,它定义了如何获取数据。Resolver 与 Schema 中定义的字段对应,它负责将查询请求转换为数据操作,并将操作结果返回给客户端。
以下是一个简单的 Resolver 示例:
const resolvers = {
Query: {
user: (_, { id }) => getUserById(id),
},
Mutation: {
createUser: (_, { input }) => createUser(input),
},
};这个 Resolver 定义了 user 查询和 createUser 变更的操作实现,在这里我们假设 getUserById 和 createUser 是数据库操作。
在前端领域,GraphQL 的应用主要分为两个方面:与后端交互和客户端数据管理。接下来我们将分别介绍这两个方面的应用实践。
与后端交互
在与后端交互时,GraphQL 可以替代传统的 RESTful API,提供更灵活、高效的数据交互方式。我们可以通过 GraphQL 来定义需要获取的数据结构,减少网络传输的数据量,并且可以一次性获取多个接口的数据,提高数据获取的效率。
使用 Apollo Client
在前端中,我们可以使用 Apollo Client 来与 GraphQL API 进行交互。Apollo Client 是一个开源的 JavaScript 客户端,可以与 GraphQL API 进行交互,并提供了数据缓存、错误处理等功能。
以下是一个简单的 Apollo Client 示例:
// www.javascriptcn.com code example
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
const client = new ApolloClient({
uri: 'https://api.example.com/graphql',
cache: new InMemoryCache(),
});
client
.query({
query: gql`
query {
user(id: "1") {
id
name
age
}
}
`,
})
.then((result) => console.log(result));这个示例使用了 Apollo Client 的 query 方法,向 GraphQL API 发起了一个查询请求,并返回了查询结果。
使用 Relay
除了 Apollo Client,我们还可以使用 Facebook 开源的 Relay 来与 GraphQL API 进行交互。Relay 是一个强类型的 JavaScript 客户端,可以自动化生成数据查询和管理代码,提高开发效率。
以下是一个简单的 Relay 示例:
// www.javascriptcn.com code example
import { graphql, QueryRenderer } from 'react-relay';
const UserQuery = graphql`
query UserQuery($id: ID!) {
user(id: $id) {
id
name
age
}
}
`;
const variables = { id: '1' };
<QueryRenderer
environment={environment}
query={UserQuery}
variables={variables}
render={({ error, props }) => {
if (error) {
return <div>{error.message}</div>;
} else if (props) {
return (
<div>
<div>{props.user.id}</div>
<div>{props.user.name}</div>
<div>{props.user.age}</div>
</div>
);
} else {
return <div>Loading...</div>;
}
}}
/>;这个示例使用了 Relay 的 graphql 方法,定义了一个 UserQuery 查询,并传入了查询变量。在渲染时,使用 QueryRenderer 组件来发起查询请求,并根据查询结果渲染页面。
客户端数据管理
在客户端数据管理方面,GraphQL 可以替代传统的状态管理库,提供更灵活、高效的数据管理方式。我们可以使用 GraphQL 来定义客户端的数据结构,并使用 GraphQL 的查询和变更操作来管理数据。
使用 Apollo Client
在客户端数据管理方面,Apollo Client 提供了一些方便的工具来管理数据,包括 useQuery、useMutation、useSubscription 等 Hook。
以下是一个简单的 Apollo Client 示例:
// www.javascriptcn.com code example
import { useQuery, useMutation, gql } from '@apollo/client';
const UserQuery = gql`
query UserQuery($id: ID!) {
user(id: $id) {
id
name
age
}
}
`;
const CreateUserMutation = gql`
mutation CreateUserMutation($input: CreateUserInput!) {
createUser(input: $input) {
id
name
age
}
}
`;
const User = ({ id }) => {
const { loading, error, data } = useQuery(UserQuery, {
variables: { id },
});
if (loading) return <div>Loading...</div>;
if (error) return <div>{error.message}</div>;
return (
<div>
<div>{data.user.id}</div>
<div>{data.user.name}</div>
<div>{data.user.age}</div>
</div>
);
};
const CreateUser = () => {
const [createUser] = useMutation(CreateUserMutation);
const handleSubmit = (event) => {
event.preventDefault();
const name = event.target.elements.name.value;
const age = event.target.elements.age.value;
createUser({
variables: { input: { name, age } },
update: (cache, { data: { createUser } }) => {
cache.modify({
fields: {
users(existingUsers = []) {
const newUserRef = cache.writeFragment({
data: createUser,
fragment: gql`
fragment NewUser on User {
id
name
age
}
`,
});
return [...existingUsers, newUserRef];
},
},
});
},
});
};
return (
<form onSubmit={handleSubmit}>
<input type="text" name="name" />
<input type="number" name="age" />
<button type="submit">Create User</button>
</form>
);
};这个示例使用了 Apollo Client 的 useQuery 和 useMutation Hook,分别定义了 UserQuery 查询和 CreateUserMutation 变更,并使用这两个 Hook 来管理数据。在 CreateUser 组件中,我们使用 useMutation Hook 来创建一个新用户,并在操作成功后更新缓存中的用户列表。
使用 Relay
在客户端数据管理方面,Relay 提供了一些方便的工具来管理数据,包括 useFragment、usePagination、useRefetchableFragment 等 Hook。
以下是一个简单的 Relay 示例:
// www.javascriptcn.com code example
import { graphql, useQuery, useMutation } from 'react-relay';
const UserQuery = graphql`
query UserQuery($id: ID!) {
user(id: $id) {
id
name
age
}
}
`;
const CreateUserMutation = graphql`
mutation CreateUserMutation($input: CreateUserInput!) {
createUser(input: $input) {
id
name
age
}
}
`;
const User = ({ id }) => {
const { error, props } = useQuery(UserQuery, { id });
if (error) return <div>{error.message}</div>;
if (!props) return <div>Loading...</div>;
return (
<div>
<div>{props.user.id}</div>
<div>{props.user.name}</div>
<div>{props.user.age}</div>
</div>
);
};
const CreateUser = () => {
const [commit, isInFlight] = useMutation(CreateUserMutation);
const handleSubmit = (event) => {
event.preventDefault();
const name = event.target.elements.name.value;
const age = event.target.elements.age.value;
const input = { name, age };
commit({
variables: { input },
updater: (store) => {
const payload = store.getRootField('createUser');
const user = payload.getLinkedRecord('user');
const root = store.getRoot();
const users = root.getLinkedRecord('users');
const edges = users.getLinkedRecords('edges');
const newEdge = store.create('client:newEdge', 'UserEdge');
newEdge.setLinkedRecord(user, 'node');
edges.push(newEdge);
users.setLinkedRecords(edges, 'edges');
},
optimisticUpdater: (store) => {
const id = 'client:newUser:' + Date.now();
const user = store.create(id, 'User');
user.setValue(id, 'id');
user.setValue(name, 'name');
user.setValue(age, 'age');
const root = store.getRoot();
const users = root.getLinkedRecord('users');
const edges = users.getLinkedRecords('edges');
const newEdge = store.create('client:newEdge:' + Date.now(), 'UserEdge');
newEdge.setLinkedRecord(user, 'node');
edges.push(newEdge);
users.setLinkedRecords(edges, 'edges');
},
});
};
return (
<form onSubmit={handleSubmit}>
<input type="text" name="name" />
<input type="number" name="age" />
<button type="submit" disabled={isInFlight}>
Create User
</button>
</form>
);
};这个示例使用了 Relay 的 useQuery 和 useMutation Hook,分别定义了 UserQuery 查询和 CreateUserMutation 变更,并使用这两个 Hook 来管理数据。在 CreateUser 组件中,我们使用 useMutation Hook 来创建一个新用户,并在操作成功后更新缓存中的用户列表。
结语
本文介绍了 GraphQL 在前端领域的应用实践,包括与后端交互和客户端数据管理。通过学习本文,读者可以深入了解 GraphQL 的基础概念和使用方式,并学习到如何在前端中使用 Apollo Client 和 Relay 来与 GraphQL API 进行交互和管理数据。GraphQL 在前端领域的应用越来越广泛,相信本文对读者有一定的指导意义。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d2ad6ea941bf713452ece2