GraphQL 是现代化的 API ,它具有强大的功能和灵活性。然而,由于 GraphQL 查询允许客户端定义其返回的数据结构,因此存在一些安全问题。攻击者可以通过创建查询,访问应用程序中未经授权的信息或破坏系统。为了解决这个问题,可以使用 TypeScript,一个强类型的语言,来确保所有的 GraphQL 查询或变异都具有正确的类型和参数。
TypeScript 简介
TypeScript 是一个由 Microsoft 开发的开源编程语言。它是 JavaScript 的超集,提供了类型和更严格的语义分析,这使得代码更健壮和易于维护。TypeScript 通过使用静态类型检查,在编译时捕捉到潜在的编程错误,提高了代码的可读性、可维护性和可扩展性。
GraphQL 和 TypeScript
GraphQL 是一种查询语言,它定义了客户端可以使用的 API,包括查询、变异和订阅等操作。GraphQL 可以使用多种语言实现,包括 TypeScript。TypeScript 具有显式类型声明、代码分析和静态类型检查等功能,因此可以确保 GraphQL 服务器的代码不会在使用时出现类型错误或其他错误。
TypeScript 和 GraphQL 的结合可以使 GraphQL 代码变得更加清晰和易于维护。当您使用 TypeScript 来开发 GraphQL 服务器时,它将通过强类型检查帮助您识别和防止潜在的编程错误。
使用 TypeScript 和 GraphQL
在使用 TypeScript 来编写 GraphQL 服务的代码时,您需要遵循以下步骤:
安装相关的包
首先,您需要安装 graphql 和 graphql-tools 的 npm 包。
npm install graphql graphql-tools
定义类型
接下来,定义 GraphQL 的类型。由于我们使用 TypeScript,所以我们需要创建一个将类型定义编译为 TypeScript 接口的工具。以下示例使用 makeExecutableSchema 函数、typeDefs 和 resolvers 来定义类型。
// www.javascriptcn.com code example
import { makeExecutableSchema } from 'graphql-tools';
import { GraphQLSchema } from 'graphql';
const typeDefs = `
type User {
id: ID!
name: String!
email: String!
}
type Query {
getUser(id: ID!): User
}
`;
const resolvers = {
Query: {
getUser: async (_, args, context) => {
// 省略实现
},
},
};
const schema: GraphQLSchema = makeExecutableSchema({
typeDefs,
resolvers,
});
export default schema;此处定义了一个 User 类型和一个查询 getUser。getUser 函数返回 User 对象,包含用户的 ID、名称和电子邮件。您可以按需添加其他类型和查询、变更和订阅等操作。
实现解析器
接下来,您需要实现查询操作的解析器。以下示例实现了上一步中的 getUser 操作。
// www.javascriptcn.com code example
const resolvers = {
Query: {
getUser: async (_, args, context): Promise<User> => {
const { id } = args;
const user = await getUserById(id);
if (!user) {
throw new Error(`User with ID ${id} not found`);
}
return user;
},
},
};此处解析器通过调用 getUserById 函数获取用户的数据。如果找不到用户,则抛出一个错误。由于 TypeScript 在编译时可以捕获到这些异常,因此可以确保代码没有运行时错误。
创建服务器
最后,您需要使用 express、apollo-server等创建一个 HTTP 将请求路由到 GraphQL 解析器的服务器。以下示例使用 apollo-server-express 库创建服务器。
// www.javascriptcn.com code example
import express from 'express';
import { ApolloServer } from 'apollo-server-express';
import schema from './schema';
const app = express();
const server = new ApolloServer({ schema });
server.applyMiddleware({ app });
app.listen({ port: 4000 }, () => {
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`);
});使用 TypeScript 类型
如果使用 TypeScript 编写客户端代码,则可以使用自动生成的类型声明来调用 GraphQL API。例如,在客户端应用程序中使用 Apollo GraphQL 客户端来调用 getUser 查询。以下示例使用 useQuery 钩子来获取用户信息:
// www.javascriptcn.com code example
import { useQuery } from '@apollo/client';
import { GET_USER } from './queries';
interface User {
id: string;
name: string;
email: string;
}
const UserDetails = () => {
const { loading, error, data } = useQuery<{ getUser: User }>(GET_USER, { variables: { id: '123' } });
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return (
<div>
<h2>User Details</h2>
<p>ID: {data.getUser.id}</p>
<p>Name: {data.getUser.name}</p>
<p>Email: {data.getUser.email}</p>
</div>
);
};如上所述,GraphQL 和 TypeScript 的结合可以使开发更加容易、安全和可维护。TypeScript 强大且易于使用,需要花费一定时间来学习,但一旦学会,它将使您的代码更加清晰易懂。通过以下步骤:定义类型、实现解析器、创建服务器,再配合自动生成的类型声明。您将获得一个强大且安全的 GraphQL API ,并且可以在项目的后期维护和拓展过程中更加轻松。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67cff982e46428fe9ec5c751