Serverless Framework项目架构组织与跨服务授权、集中资源配置问题咨询
嘿,作为一个用Serverless Framework折腾过不少后端项目的开发者,我完全懂你一开始遇到的那些头疼问题——冗余依赖、跨服务授权、资源分散部署麻烦,这都是新手入门时很容易踩的坑。咱们一个个来解决:
问题1:如何配置auth-service作为其他服务的授权器
你想到用auth函数的ARN来做授权器的思路是完全可行的,而且这也是跨服务授权的标准做法,不过有几个细节要注意,能让你配置起来更顺畅:
先部署auth服务并导出ARN:在auth-service的
serverless.yml里,把授权函数的ARN作为输出变量,这样其他服务就能直接引用,不用手动复制ARN(避免出错):# auth-service/serverless.yml functions: jwtAuthorizer: handler: handler.authorize # 其他配置... outputs: AuthorizerFunctionArn: Value: !GetAtt JwtAuthorizerLambdaFunction.Arn在其他服务中引用这个ARN:比如在customers的
serverless.yml里,给需要授权的HTTP事件配置authorizer,直接通过CloudFormation的引用语法调用auth服务的输出:# customers/serverless.yml functions: getCustomer: handler: handler.getCustomer events: - http: path: customers/{id} method: get authorizer: type: TOKEN arn: ${cf:auth-service-stack-name.AuthorizerFunctionArn} # 指定从请求头拿token的位置,一般是Authorization identitySource: event.headers.Authorization这里的
auth-service-stack-name是你部署auth服务时指定的栈名(如果没指定,默认是auth-service-${stage})。注意部署顺序:因为products和customers依赖auth服务的输出,所以要先部署auth服务,再部署其他服务。如果用后面说的批量部署工具,就能自动处理这个依赖顺序。
问题2:更优的项目架构与集中资源管理
你现在每个服务单独一个serverless.yml的方式确实会导致资源分散、部署繁琐,推荐用**单仓库多服务(Monorepo)**的结构,配合Serverless Framework的serverless-compose工具,既能解决冗余依赖问题,又能集中管理资源、一键部署所有服务。
推荐的项目结构
|--services | |--auth-service | | |--handler.js | | |--package.json # 只装auth需要的依赖(比如bcrypt) | |--products | | |--handler.js | | |--package.json # 只装products需要的依赖 | |--customers | | |--handler.js | | |--package.json # 只装customers需要的依赖 |--resources | |--dynamodb.yml # 集中定义所有DynamoDB表 | |--iam-roles.yml # 集中定义共享IAM角色/权限 |--serverless-compose.yml # 根配置,管理所有服务 |--package.json # 根依赖,比如serverless-compose
核心优势说明
集中管理资源:把DynamoDB、S3这些共享资源放在
resources目录下,在serverless-compose.yml或者单独的资源栈里定义,避免每个服务重复写资源配置。比如在resources/dynamodb.yml里定义表:# resources/dynamodb.yml Resources: CustomerTable: Type: AWS::DynamoDB::Table Properties: TableName: CustomerTable-${stage} AttributeDefinitions: - AttributeName: id AttributeType: S KeySchema: - AttributeName: id KeyType: HASH BillingMode: PAY_PER_REQUEST然后在根配置里引入这个资源,或者单独部署一个资源栈,其他服务通过CloudFormation输出引用表的ARN。
一键批量部署:用
serverless-compose.yml来管理所有服务的依赖和部署,配置示例:# serverless-compose.yml services: auth-service: path: services/auth-service # 可以指定部署参数 parameters: stage: ${env:STAGE, 'dev'} products: path: services/products dependsOn: auth-service # 自动等待auth部署完成再部署 parameters: stage: ${env:STAGE, 'dev'} customers: path: services/customers dependsOn: auth-service parameters: stage: ${env:STAGE, 'dev'}这样你只需要在根目录运行
serverless deploy,就能一键部署所有服务,或者用serverless deploy --service customers单独部署某个服务。避免冗余依赖:每个服务的
package.json只装自己需要的依赖,Serverless Framework在打包时会单独处理每个服务的依赖,不会把其他服务的包带进去,完美解决你一开始遇到的node_modules冗余问题。
补充小技巧
- 如果不想用
serverless-compose,也可以用Lerna或者Nx这类Monorepo工具来管理依赖,配合Serverless的package.individually: true选项,不过serverless-compose是Serverless官方推出的,对Serverless项目的支持更贴合。 - 对于共享的工具函数(比如通用的DynamoDB操作),可以在根目录建一个
shared文件夹,然后通过npm的本地包或者符号链接让各个服务引用,避免代码重复。
备注:内容来源于stack exchange,提问作者Ujjwal Saxena

