用 Serverless 架构快速搭建 GraphQL 的教程

GraphQL 是一种基于 RESTful API 的替代方案,它可以让开发者更容易地在客户端和服务器之间进行数据交互。在前端开发中,常常需要通过 GraphQL 与后端服务器进行数据通信,而在传统的服务器架构中,搭建 GraphQL 服务需要考虑诸多技术细节和架构设计,这对于新手来说可能会是一个难以跨越的门槛。但是,借助 Serverless 架构,我们可以快速轻松地搭建一套高效的 GraphQL 服务。

什么是 Serverless 架构

Serverless 架构是一种无服务化的计算模式,与传统的服务器模式相比,最大的不同在于 Serverless 架构并不需要用户自己搭建、维护服务器硬件和软件环境。相反,Serverless 架构是一种按使用资源付费的模式,即只有在需要使用计算资源的时候才会被分配计算资源,这样能够大大降低开发和运维的成本,提高系统的可用性和灵活性。

常见的 Serverless 服务提供商有 AWS Lambda、Azure Functions、Google Cloud Functions 等。

使用 Serverless 架构搭建 GraphQL 服务

在本教程中,我们将使用 AWS Lambda 和 AWS API Gateway 实现一个简单的 GraphQL 服务。

第一步:创建 Serverless 项目

首先,在 AWS 控制台中创建 Lambda 函数,选择您喜欢的语言,本教程中我们将选择 Node.js。

其次,在 AWS 控制台中创建 AWS API Gateway,选择 Lambda Proxy 集成,将 API Gateway 与 Lambda 函数关联起来。

当您完成此步骤后,您将得到一个 API Gateway 的 URL,我们将在下一步中使用它。

第二步:安装依赖包和配置 GraphQL

接下来,我们需要安装 npm 包,并探究使用 Amazon API Gateway 和 AWS Lambda 的 GraphQL 架构的好处体验。所以,我们需要建立一个带有以下依赖关系的 package.json 文件:

{
  "name": "aws-lambda-graphql-api",
  "version": "1.0.0",
  "description": "A simple GraphQL API example using AWS Lambda and Amazon API Gateway",
  "scripts": {
    "deploy": "aws cloudformation package --template-file serverless.yaml --s3-bucket <your-bucket-name> --output-template-file packaged.yaml && aws cloudformation deploy --template-file ${PWD}/packaged.yaml --stack-name aws-lambda-graphql-api --capabilities CAPABILITY_IAM"
  },
  "dependencies": {
    "aws-sdk": "^2.683.0",
    "graphql": "^15.5.1",
    "graphql-request": "^3.5.0",
    "graphql-tools": "^6.2.7"
  },
  "devDependencies": {
    "serverless": "^2.20.0",
    "serverless-apigateway-service-proxy": "^2.3.3",
    "serverless-aws-documentation": "^1.1.0",
    "serverless-offline": "^8.0.0",
    "serverless-plugin-aws-alerts": "^4.2.2",
    "serverless-plugin-typescript": "^2.4.0",
    "typescript": "^4.2.3"
  }
}

然后,我们需要创建一个 serverless.yaml 文件,用于配置 AWS Lambda 函数和 API Gateway

service: aws-lambda-graphql-api
frameworkVersion: '2'

provider:
  name: aws
  runtime: nodejs12.x
  stage: dev
  region: us-east-1
  iamRoleStatements:
    - Effect: Allow
      Action:
        - s3:*
      Resource: "*"

functions:
  app:
    handler: src/lambda.handler
    events:
      - http:
          method: post
          path: /
          integration: lambda-proxy
          cors: true
          documentation:
            summary: Execute a GraphQL Query
            description: Execute a GraphQL query on this endpoint
            requestModels:
              'application/json': ${{file(request.json)}}

plugins:
  - serverless-plugin-typescript
  - serverless-apigateway-service-proxy
  - serverless-plugin-aws-alerts

注意,这个配置中:

  • runtime 指定了使用的 nodejs12.x 运行时版本;
  • handler 指定了入口文件为 src/lambda.handler
  • events 配置了访问 API 的方式和路径,所有发起的 POST 请求都将被路由到 src/lambda.handler 文件中;
  • plugins 中配置了使用了一些基础插件,比如支持 TypeScriptAPI Gateway 代理和报警等。

接下来,让我们来配置 GraphQL 引擎。

在项目目录下创建一个名为 src 的文件夹,该文件夹包含我们 Lambda 函数的代码。

lambda 函数有固定格式的输入和输出,输入是 eventcontext,输出是 callback(error, result),本教程中,我们要使用 apollo-server-lambda 来编写 handler 函数,该函数将预处理 GraphQL 查询和响应结果:

import { ApolloServer } from 'apollo-server-lambda';
import { makeExecutableSchema } from 'graphql-tools';

const schema = `
  type Query {
    hello(name: String): String
  }
`;

const resolvers = {
  Query: {
    hello: async (_: any, { name }: { name: string }) => {
      return `Hello from Serverless, ${name || 'Anonymous'}`;
    },
  },
};

const graphqlHandler = new ApolloServer({
  schema: makeExecutableSchema({ typeDefs: schema, resolvers }),
  introspection: true,
  playground: true,
}).createHandler();

export const handler = (event: any, context: any, callback: any) => {
  context.callbackWaitsForEmptyEventLoop = false;
  const callbackFilter = (error: any, output: any) => {
    const headers = { 'Content-Type': 'application/json' };
    callback(error, { ...output, headers });
  };
  graphqlHandler(event, context, callbackFilter);
};

现在,我们已经成功地创建了一个 GraphQL 服务,并可以通过 AWS API Gateway 进行访问。

第三步:启动本地环境

在开发阶段,尤其是团队协作中,测试和调试 GraphQL 服务是非常重要的。因此,我们应该在本地搭建一套仿真的环境,并在上面测试服务是否正常运行。Serverless 提供了一个名为 serverless-offline 的插件,可以在本地启动一个仿真的 Lambda 环境和 API Gateway 环境。

首先,我们需要在项目目录下添加一个名为 serverless.yml 的配置文件:

service: aws-lambda-graphql-api-local
provider:
  name: aws
runtime: nodejs12.x
stage: local
region: ap-southeast-1
custom:
  region: local
  'serverless-offline': {
    httpPort: 3000
  }
functions:
  app:
    handler: src/lambda.handler
    events:
      - http:
          path: /
          method: any
plugins:
  - serverless-plugin-aws-alerts
  - serverless-offline
  - serverless-plugin-typescript

然后,安装 serverless-offline 插件:

npm install serverless-offline --save-dev

在本地启动仿真的环境:

serverless offline start

如果一切正常,serverless 将告诉您 API Gateway 的启动地址和端口。

现在您已经可以在本地开发环境中测试和调试 GraphQL 服务了。

第四步:部署

最后,我们需要将代码部署到 AWS Lambda 上。执行以下命令即可:

npm run deploy

serverless 将会打包整个项目,然后将本地代码推送到 AWS Lambda 上,包括运行目录、依赖项和 serverless.yaml 文件的配置。如果这一步成功,您即可访问部署在 AWS Lambda 上的 GraphQL 服务了。

至此,我们已经完成了 Serverless 架构下的 GraphQL 服务搭建,该服务可以快速、轻便、安全地运行,无需担心服务器硬件和软件的维护和运营成本。

总结

本篇文章详细地介绍了 Serverless 架构下如何快速搭建 GraphQL 服务,并提供了代码示例和详细的步骤和解释。尽管这一过程可能对初学者来说有一些技术挑战,但通过本教程,选择正确的技术路线和工具,我们相信您将可以轻松地构建一套高效稳定的 GraphQL 服务。

Good Luck & Have Fun!

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b3ad1fadd4f0e0ffcb3a8e