I thought I would start a dedicated thread for Monorepos. This is something @jayair committed to writing a few chapters about shortly.
In the mean time the following resources were shared by @jayair
Cross Stack References
Shared API Gateway Resources
Even with these resources shared, this is something I have been struggling with. So I wanted to share what I was planning and see if anyone else has info that can help. Maybe together we can compile a meaningful list.
My Current Folder Structure
package.json
webpack.config.js
.babelrc
jest.config.js
resources/
dynamo-table.yml
s3-bucket.yml
package.json
serverless.yml
services/
users/
create.js
create.test.js
list.js
list.test.js
delete.js
delete.test.js
update.js
update.test.js
get.js
get.test.js
package.json
serverless.yml
projects/
create.js
create.test.js
list.js
list.test.js
delete.js
delete.test.js
update.js
update.test.js
get.js
get.test.js
package.json
serverless.yml
etc/
...
Example Service Yaml File
service: service-name
plugins:
- serverless-webpack
- serverless-dynamodb-local
- serverless-offline
- serverless-domain-manager
- serverless-plugin-stage-variables
custom:
webpack:
webpackConfig: ../../webpack.config.js
includeModules:
forceExclude:
- aws-sdk
stage: ${opt:stage, self:provider.stage}
stageVariables:
env: ${self:custom.stage}
tables:
projects: projects-${self:custom.stage}
domains:
prod: api.example.com
stage: stage-api.example.com
dev: dev-api.example.com
customDomain:
domainName: ${self:custom.domains.${self:custom.stage}}
basePath: 'projects'
stage: ${self:custom.stage}
createRoute53Record: true
dynamodb:
start:
port: 8000
inMemory: true
migrate: true
migration:
dir: migrations
package:
exclude:
- coverage/**
- migrations/**
- .circleci/**
- .git/**
- tests/**
provider:
name: aws
runtime: nodejs8.10
stage: dev
region: us-east-1
iamRoleStatements:
- Effect: "Allow"
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:*:*:table/${self:custom.tables.projects}"
functions:
create:
handler: create.default
events:
- http:
path: /
method: post
cors: true
environment:
PROJECTS_TABLE: ${self:custom.tables.projects}
list:
handler: list.default
events:
- http:
path: /
method: get
cors: true
environment:
PROJECTS_TABLE: ${self:custom.tables.projects}
get:
handler: get.default
events:
- http:
path: /{id}
method: get
cors: true
environment:
PROJECTS_TABLE: ${self:custom.tables.projects}
update:
handler: update.default
events:
- http:
path: /{id}
method: put
cors: true
environment:
PROJECTS_TABLE: ${self:custom.tables.projects}
delete:
handler: delete.default
events:
- http:
path: /{id}
method: delete
cors: true
environment:
PROJECTS_TABLE: ${self:custom.tables.projects}
Additional Questions
- Do I need all those plugins? I want to use es6 syntax and have been using webpack prior to moving to a monorepo and am trying to figure out if I need everything in the servless.yml file for each service.
- Do i need the domain specified in each service? All are part of
api.example.com
or the other stages. - Currently I set the base path different for each service, but ideally I would be using
v1/
and in the futurev2/
for versioning. What is the recommended way to handle this? - Dynamo DB Local will only run one service, which makes sense. Is this the best way to test locally?
- I have a single endpoint that can interact with two databases (not shown here). Does it make sense to do this, or have that service call “update” on the real update endpoint. Seemed weird to have lambda call a api that is a sister service.
- Is this an ideal setup. Can I contain webpack in root?
- Does the package.json files need all the babel and webpack installations to run the serverless-webpack plugin?
- Does it make sense to keep seperate package.json file with
serverless-webpack
, since treeshaking should reduce the bundle size. Do people typically use learna or yarn workspaces, or just roll there own, or keep one package.json? - Does keep resources in a separate deploy cause problems? Does this make sense? I see the “shared API gateway” resource, and am curious if this concept exists for s3 buckets, dynamo db, cognito identity or user pools.