首页 > web前端 > js教程 > GraphQL 在现代 Web 应用程序中的应用和优势

GraphQL 在现代 Web 应用程序中的应用和优势

DDD
发布: 2024-12-23 18:58:21
原创
636 人浏览过

Applications and Advantages of GraphQL in Modern Web Applications

GraphQL 是一种现代 API 查询语言,广泛应用于现代 Web 应用程序中,因为它提供了一种高效、灵活且强大的获取数据的方式

GraphQL 基本快速应用示例:

1.后端设置(使用graphql-yoga)

首先,我们需要创建一个 GraphQL 服务器。安装 graphql-yoga 并创建一个简单的 GraphQL 模式:

npm init -y
npm install graphql yoga graphql-yoga

# server.js
const { GraphQLServer } = require('graphql-yoga');

const typeDefs = `
  type Query {
    hello: String
  }

  type Mutation {
    addMessage(message: String!): String
  }
`;

const resolvers = {
  Query: {
    hello: () => 'Hello world!',
  },
  Mutation: {
    addMessage: (_, { message }) => `You added the message "${message}"`,
  },
};

const server = new GraphQLServer({ typeDefs, resolvers });
server.start(() => console.log(`Server is running on http://localhost:4000`));
登录后复制
登录后复制
登录后复制

2.前端设置(使用Apollo Client)

接下来,我们需要在前端应用程序中配置 Apollo Client 来与我们的 GraphQL 服务器通信:

npm install apollo-boost @apollo/client graphql

# client.js
import ApolloClient from 'apollo-boost';
import { InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  uri: 'http://localhost:4000/graphql',
  cache: new InMemoryCache(),
});

export default client;
登录后复制
登录后复制
登录后复制

3.编写前端组件

现在,我们在React组件中使用Apollo Client来执行查询和突变:

// App.js
import React from 'react';
import { gql, useQuery, useMutation } from '@apollo/client';
import client from './client';

const GET_HELLO = gql`
  query GetHello {
    hello
  }
`;

const ADD_MESSAGE_MUTATION = gql`
  mutation AddMessage($message: String!) {
    addMessage(message: $message)
  }
`;

function App() {
  const { loading, error, data } = useQuery(GET_HELLO);
  const [addMessage, { data: mutationData }] = useMutation(ADD_MESSAGE_MUTATION);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return (
    <div>
      <h1>{data.hello}</h1>
      <button onClick={() => addMessage({ variables: { message: 'Hello from frontend!' } })}>
        Add Message
      </button>
      {mutationData && <p>New message: {mutationData.addMessage}</p>}
    </div>
  );
}
export default App;
登录后复制
登录后复制
登录后复制

我们创建一个 GET_HELLO 查询来获取服务器的问候语并将其显示在页面上。同时,我们定义了一个ADD_MESSAGE_MUTATION突变操作,当用户点击按钮时,它会向服务器发送一条新消息。

4. 运行应用程序

启动后端服务器:

node server.js
登录后复制
登录后复制

然后启动前端应用程序,假设创建React App:

npm start
登录后复制
登录后复制

GraphQL 基本查询

1. 查询语言:查询、变异、订阅

在 GraphQL 中,查询和突变是由类似 JSON 的结构表示的字符串。这是一个简单的例子:

# Query Example
query GetUser {
  user(id: 1) {
    name
    email
  }
}

# Mutation Example
mutation CreateUser {
  createUser(name: "Alice", email: "alice@example.com") {
    id
    name
  }
}

# Subscription Example (Assuming WebSocket)
subscription OnNewUser {
  newUser {
    id
    name
  }
}
登录后复制
登录后复制

在上面的代码中,GetUser 查询请求用户 ID 为 1 的用户的姓名和电子邮件。CreateUser 突变创建一个新用户并返回新用户的 ID 和名称。 OnNewUser 订阅等待新用户创建并返回新用户的信息。

2. 类型系统

在后端,我们定义了一个 GraphQL 模式来描述这些类型:

type User {
  id: ID!
  name: String!
  email: String!
}

type Mutation {
  createUser(name: String!, email: String!): User
}

type Subscription {
  newUser: User
}
登录后复制
登录后复制

这里我们定义了一个 User 对象类型,一个用于变异操作的 Mutation 类型,以及一个用于订阅操作的 Subscription 类型。

3. 查询结构:字段和参数

查询结构由字段和参数组成。在上面的查询示例中,user 是字段,id 和 email 是 user 字段的子字段。 id:1等参数用于自定义查询。

4. 层次结构和嵌套

GraphQL 查询可以嵌套。这是一个更复杂的示例:

query GetUsersAndPosts {
  users {
    id
    name
    posts {
      id
      title
      content
      author {
        id
        name
      }
    }
  }
}
登录后复制
登录后复制

此查询请求所有用户及其各自的帖子,其中还包括有关作者的信息。层次结构允许在一个请求中检索多个级别的数据。

客户端代码示例(使用 Apollo 客户端)

npm init -y
npm install graphql yoga graphql-yoga

# server.js
const { GraphQLServer } = require('graphql-yoga');

const typeDefs = `
  type Query {
    hello: String
  }

  type Mutation {
    addMessage(message: String!): String
  }
`;

const resolvers = {
  Query: {
    hello: () => 'Hello world!',
  },
  Mutation: {
    addMessage: (_, { message }) => `You added the message "${message}"`,
  },
};

const server = new GraphQLServer({ typeDefs, resolvers });
server.start(() => console.log(`Server is running on http://localhost:4000`));
登录后复制
登录后复制
登录后复制

在此 React 组件中,我们使用 useQuery 从 GraphQL 服务器获取数据并呈现有关用户及其帖子的信息。这就是 GraphQL 查询、类型系统和层次结构发挥作用的方式。

GraphQL 架构

GraphQL 模式定义语言(SDL)是一种用于描述 GraphQL 模式的语言。它以简洁、人类可读的格式定义数据类型、查询、突变和指令。

定义类型
首先,让我们定义一些基本数据类型。例如,定义一个 User 类型和一个 Post 类型。

npm install apollo-boost @apollo/client graphql

# client.js
import ApolloClient from 'apollo-boost';
import { InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  uri: 'http://localhost:4000/graphql',
  cache: new InMemoryCache(),
});

export default client;
登录后复制
登录后复制
登录后复制

这里,用户类型有 id、用户名、电子邮件字段和链接到多个帖子的帖子字段。 Post 类型包含 id、标题、内容字段和指向用户的作者字段。

查询根和变异根
接下来,定义 GraphQL 查询根(Query)和变异根(Mutation)类型,它们是客户端请求数据和修改数据的入口点。

// App.js
import React from 'react';
import { gql, useQuery, useMutation } from '@apollo/client';
import client from './client';

const GET_HELLO = gql`
  query GetHello {
    hello
  }
`;

const ADD_MESSAGE_MUTATION = gql`
  mutation AddMessage($message: String!) {
    addMessage(message: $message)
  }
`;

function App() {
  const { loading, error, data } = useQuery(GET_HELLO);
  const [addMessage, { data: mutationData }] = useMutation(ADD_MESSAGE_MUTATION);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return (
    <div>
      <h1>{data.hello}</h1>
      <button onClick={() => addMessage({ variables: { message: 'Hello from frontend!' } })}>
        Add Message
      </button>
      {mutationData && <p>New message: {mutationData.addMessage}</p>}
    </div>
  );
}
export default App;
登录后复制
登录后复制
登录后复制

在查询类型中,我们定义了获取单个用户、所有用户、单个帖子和所有帖子的查询。在 Mutation 类型中,我们定义了创建新用户和新帖子的操作。

理解和使用指令
指令是 GraphQL 模式中更改执行行为的指令。它们可以应用于类型系统定义的任何部分,例如字段、输入类型、对象类型等。下面演示如何使用自定义 @auth 指令来控制访问权限。

首先,假设我们定义一个 @auth 指令来限制对某些字段的访问并要求用户登录。

node server.js
登录后复制
登录后复制

接下来,在架构中应用此指令:

npm start
登录后复制
登录后复制

在上面的示例中,me查询和用户名字段无需特殊权限即可访问,但访问用户的电子邮件字段需要管理员权限(由@auth(requires: ADMIN)指令指定)。

GraphQL 高级应用

1. 分页

使用 GraphQL 基于游标的分页来提高性能和用户体验。

架构定义:

# Query Example
query GetUser {
  user(id: 1) {
    name
    email
  }
}

# Mutation Example
mutation CreateUser {
  createUser(name: "Alice", email: "alice@example.com") {
    id
    name
  }
}

# Subscription Example (Assuming WebSocket)
subscription OnNewUser {
  newUser {
    id
    name
  }
}
登录后复制
登录后复制

解析器示例:

type User {
  id: ID!
  name: String!
  email: String!
}

type Mutation {
  createUser(name: String!, email: String!): User
}

type Subscription {
  newUser: User
}
登录后复制
登录后复制

2. 错误处理

自定义错误处理,提高客户端处理错误的能力。

解析器示例:

query GetUsersAndPosts {
  users {
    id
    name
    posts {
      id
      title
      content
      author {
        id
        name
      }
    }
  }
}
登录后复制
登录后复制

3. 自定义指令

创建自定义指令来实现特定的业务逻辑或安全要求。

架构定义:

import { gql, useQuery } from '@apollo/client';

const GET_USERS_AND_POSTS = gql`
  query GetUsersAndPosts {
    users {
      id
      name
      posts {
        id
        title
        content
        author {
          id
          name
        }
      }
    }
  }
`;

function App() {
  const { loading, error, data } = useQuery(GET_USERS_AND_POSTS);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :-(</p>;

  return (
    <div>
      {data.users.map(user => (
        <div key={user.id}>
          <h2>{user.name}</h2>
          <ul>
            {user.posts.map(post => (
              <li key={post.id}>
                <h3>{post.title}</h3>
                <p>{post.content}</p>
                <p>Author: {post.author.name}</p>
              </li>
            ))}
          </ul>
        </div>
      ))}
    </div>
  );
}

export default App;
登录后复制

解析器示例:

type User {
  id: ID!
  username: String!
  email: String!
  posts: [Post!]!
}

type Post {
  id: ID!
  title: String!
  content: String!
  author: User!
}
登录后复制

确保在您的 GraphQL 服务器配置中注册此指令处理程序。

4.GraphQL联邦

Federation 允许构建由多个服务组成的单个 GraphQL API。

服务架构:

npm init -y
npm install graphql yoga graphql-yoga

# server.js
const { GraphQLServer } = require('graphql-yoga');

const typeDefs = `
  type Query {
    hello: String
  }

  type Mutation {
    addMessage(message: String!): String
  }
`;

const resolvers = {
  Query: {
    hello: () => 'Hello world!',
  },
  Mutation: {
    addMessage: (_, { message }) => `You added the message "${message}"`,
  },
};

const server = new GraphQLServer({ typeDefs, resolvers });
server.start(() => console.log(`Server is running on http://localhost:4000`));
登录后复制
登录后复制
登录后复制

服务 B 架构:

npm install apollo-boost @apollo/client graphql

# client.js
import ApolloClient from 'apollo-boost';
import { InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  uri: 'http://localhost:4000/graphql',
  cache: new InMemoryCache(),
});

export default client;
登录后复制
登录后复制
登录后复制

5.复杂查询优化

使用 GraphQL 的字段解析器和数据加载器来优化性能。

数据加载器示例:

// App.js
import React from 'react';
import { gql, useQuery, useMutation } from '@apollo/client';
import client from './client';

const GET_HELLO = gql`
  query GetHello {
    hello
  }
`;

const ADD_MESSAGE_MUTATION = gql`
  mutation AddMessage($message: String!) {
    addMessage(message: $message)
  }
`;

function App() {
  const { loading, error, data } = useQuery(GET_HELLO);
  const [addMessage, { data: mutationData }] = useMutation(ADD_MESSAGE_MUTATION);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return (
    <div>
      <h1>{data.hello}</h1>
      <button onClick={() => addMessage({ variables: { message: 'Hello from frontend!' } })}>
        Add Message
      </button>
      {mutationData && <p>New message: {mutationData.addMessage}</p>}
    </div>
  );
}
export default App;
登录后复制
登录后复制
登录后复制

GraphQL 的特点和优势

  • 性能优化:通过按需获取数据,降低网络传输开销,提高页面加载速度。
  • 减少错误:客户端定义查询结构,服务器返回预期形状,减少接口不匹配导致的错误。
  • 更好的API设计:强类型系统保证了数据的一致性和正确性,使API更易于理解和维护。
  • 客户端控制:客户端可以决定获取多少数据以及何时获取,提高了用户体验。
  • 缓存优化:客户端可以根据返回的数据结构更轻松地实现缓存策略。
  • 降低后端复杂度:后端不再需要创建多个API端点来满足不同客户端的需求。

以上是GraphQL 在现代 Web 应用程序中的应用和优势的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板