├── ch4
├── cdn-site
│ ├── dist
│ │ ├── robots.txt
│ │ ├── favicon.ico
│ │ └── phenomic
│ │ │ └── content
│ │ │ └── posts
│ │ │ ├── item
│ │ │ ├── third-post.json
│ │ │ ├── fourth-post.json
│ │ │ ├── second-post.json
│ │ │ └── fifth-post.json
│ │ │ └── by-default
│ │ │ └── 1
│ │ │ └── desc
│ │ │ └── date
│ │ │ ├── limit-2.json
│ │ │ └── limit-2
│ │ │ ├── after-Zmlyc3QtcG9zdA==.json
│ │ │ ├── after-ZmlmdGgtcG9zdA==.json
│ │ │ ├── after-Zm91cnRoLXBvc3Q=.json
│ │ │ ├── after-dGhpcmQtcG9zdA==.json
│ │ │ └── after-c2Vjb25kLXBvc3Q=.json
│ ├── .gitignore
│ ├── content
│ │ └── posts
│ │ │ ├── fourth-post.md
│ │ │ ├── second-post.md
│ │ │ ├── third-post.md
│ │ │ ├── fifth-post.md
│ │ │ └── first-post.md
│ ├── README.md
│ └── serverless.yml
├── cdn-json
│ ├── .gitignore
│ └── package.json
├── cdn-lambda
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── cdn-service
│ ├── .gitignore
│ ├── package.json
│ ├── README.md
│ └── handler.js
├── cdn-invalidate
│ ├── .gitignore
│ ├── package.json
│ └── includes.yml
├── cdn-dns
│ ├── .gitignore
│ ├── src
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── App.test.js
│ │ ├── App.css
│ │ └── App.js
│ ├── public
│ │ ├── favicon.ico
│ │ └── manifest.json
│ ├── README.md
│ ├── serverless.yml
│ └── package.json
├── cdn-spa
│ ├── .gitignore
│ ├── src
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── App.test.js
│ │ ├── App.css
│ │ └── App.js
│ ├── public
│ │ ├── favicon.ico
│ │ └── manifest.json
│ ├── README.md
│ ├── serverless.yml
│ └── package.json
└── README.md
├── ch11
├── azure
│ ├── .gitignore
│ ├── handler.js
│ ├── package.json
│ └── README.md
├── gcp
│ ├── .gitignore
│ ├── index.js
│ ├── package.json
│ └── README.md
└── README.md
├── ch3
├── saga
│ ├── .gitignore
│ ├── data
│ │ ├── order.json
│ │ └── reservation.json
│ └── package.json
├── esg-inbound
│ ├── .gitignore
│ ├── package.json
│ ├── README.md
│ └── serverless.yml
├── bff-graphql-crud
│ ├── .gitignore
│ ├── schema
│ │ ├── thing
│ │ │ ├── index.js
│ │ │ ├── resolvers.js
│ │ │ └── typedefs.js
│ │ └── index.js
│ └── package.json
├── bff-rest-search
│ ├── .gitignore
│ ├── includes.yml
│ └── package.json
├── esg-outbound
│ ├── .gitignore
│ ├── package.json
│ ├── serverless.yml
│ └── README.md
├── esg-sqs-inbound
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── bff-rest-analytics
│ ├── .gitignore
│ └── package.json
├── event-orchestration
│ ├── .gitignore
│ ├── data
│ │ ├── order.json
│ │ └── reservation.json
│ ├── package.json
│ └── serverless.yml
└── README.md
├── ch5
├── dr
│ ├── .gitignore
│ ├── recovery-account
│ │ └── package.json
│ ├── src1-account
│ │ └── package.json
│ └── README.md
├── waf
│ ├── .gitignore
│ ├── build
│ │ └── index.html
│ ├── README.md
│ └── package.json
├── graphql-jwt
│ ├── .gitignore
│ ├── schema
│ │ ├── thing
│ │ │ ├── index.js
│ │ │ ├── resolvers.js
│ │ │ ├── model.js
│ │ │ └── typedefs.js
│ │ └── directives.js
│ ├── serverless.yml
│ ├── lib
│ │ └── fixtures.js
│ └── package.json
├── jwt-filter
│ ├── .gitignore
│ └── package.json
├── ssl-cert
│ ├── .gitignore
│ ├── build
│ │ └── index.html
│ ├── README.md
│ └── package.json
├── account-as-code
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── cognito-pool
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── cognito-authorizer
│ ├── .gitignore
│ ├── package.json
│ ├── handler.js
│ ├── serverless.yml
│ └── README.md
├── custom-authorizer
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── envelope-encryption
│ ├── .gitignore
│ └── package.json
├── cognito-signin
│ ├── .gitignore
│ ├── src
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── authenticate
│ │ │ └── index.js
│ │ ├── App.test.js
│ │ └── Home.css
│ ├── public
│ │ ├── favicon.ico
│ │ └── manifest.json
│ ├── README.md
│ └── package.json
└── README.md
├── ch2
├── event-first
│ ├── .gitignore
│ ├── package.json
│ ├── serverless.yml
│ └── README.md
├── data-lake-es
│ ├── .gitignore
│ ├── README.md
│ └── package.json
├── data-lake-s3
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── db-first-cognito
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── replaying-events
│ ├── .gitignore
│ ├── index.js
│ ├── handler.js
│ ├── serverless.yml
│ ├── README.md
│ └── package.json
├── bi-directional-sync
│ ├── .gitignore
│ └── package.json
├── db-first-dynamodb
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── materialized-view-es
│ ├── .gitignore
│ └── package.json
├── materialized-view-s3
│ ├── .gitignore
│ └── package.json
├── micro-event-store
│ ├── .gitignore
│ └── package.json
├── materialized-view-cognito
│ ├── .gitignore
│ └── package.json
└── materialized-view-dynamodb
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── ch6
├── pipeline
│ ├── .gitignore
│ ├── .npmrc-conf
│ ├── README.md
│ ├── serverless.yml
│ ├── package.json
│ └── .gitlab-ci.yml
├── unit-testing
│ ├── .eslintignore
│ ├── test
│ │ ├── helper.js
│ │ └── unit
│ │ │ └── utils
│ │ │ └── index.test.js
│ ├── .npmrc-conf
│ ├── .gitignore
│ ├── README.md
│ ├── .editorconfig
│ ├── .nycrc
│ ├── src
│ │ ├── connector
│ │ │ └── stream.js
│ │ └── get
│ │ │ └── index.js
│ ├── .babelrc
│ └── .gitlab-ci.yml
├── integration-testing
│ ├── .eslintignore
│ ├── test
│ │ ├── helper.js
│ │ ├── int
│ │ │ ├── mocks.js
│ │ │ └── save
│ │ │ │ └── index.test.js
│ │ └── unit
│ │ │ └── utils
│ │ │ └── index.test.js
│ ├── .npmrc-conf
│ ├── .gitignore
│ ├── README.md
│ ├── .editorconfig
│ ├── .nycrc
│ ├── src
│ │ ├── connector
│ │ │ └── stream.js
│ │ └── get
│ │ │ └── index.js
│ ├── .babelrc
│ └── fixtures
│ │ └── dynamodb.us-east-1.amazonaws.com-443
│ │ ├── save
│ │ └── get
├── feature-flag
│ ├── .gitignore
│ ├── src
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── authenticate
│ │ │ └── index.js
│ │ ├── App.test.js
│ │ └── Home.css
│ ├── public
│ │ ├── favicon.ico
│ │ └── manifest.json
│ ├── README.md
│ └── package.json
├── contract-testing-sync
│ ├── bff
│ │ ├── .eslintignore
│ │ ├── test
│ │ │ ├── helper.js
│ │ │ ├── int
│ │ │ │ ├── mocks.js
│ │ │ │ └── save
│ │ │ │ │ └── index.test.js
│ │ │ └── unit
│ │ │ │ └── utils
│ │ │ │ └── index.test.js
│ │ ├── .npmrc-conf
│ │ ├── .gitignore
│ │ ├── fixtures
│ │ │ ├── frontend
│ │ │ │ ├── get
│ │ │ │ └── save
│ │ │ └── dynamodb.us-east-1.amazonaws.com-443
│ │ │ │ ├── save
│ │ │ │ └── get
│ │ ├── .editorconfig
│ │ ├── .nycrc
│ │ ├── .babelrc
│ │ └── src
│ │ │ └── get
│ │ │ └── index.js
│ ├── frontend
│ │ ├── .gitignore
│ │ ├── package.json
│ │ └── fixtures
│ │ │ └── 0.0.0.0-3001
│ │ │ ├── get
│ │ │ └── save
│ └── README.md
├── transitive-testing
│ ├── author-bff
│ │ ├── .eslintignore
│ │ ├── test
│ │ │ ├── helper.js
│ │ │ ├── int
│ │ │ │ └── mocks.js
│ │ │ └── unit
│ │ │ │ └── utils
│ │ │ │ └── index.test.js
│ │ ├── .npmrc-conf
│ │ ├── .gitignore
│ │ ├── fixtures
│ │ │ ├── author-frontend
│ │ │ │ ├── get-thing0
│ │ │ │ └── save-thing0
│ │ │ └── dynamodb.us-east-1.amazonaws.com-443
│ │ │ │ ├── save-thing0
│ │ │ │ └── get-thing0
│ │ ├── .editorconfig
│ │ ├── .nycrc
│ │ ├── src
│ │ │ ├── connector
│ │ │ │ └── stream.js
│ │ │ └── get
│ │ │ │ └── index.js
│ │ └── .babelrc
│ ├── customer-bff
│ │ ├── .eslintignore
│ │ ├── test
│ │ │ ├── helper.js
│ │ │ ├── int
│ │ │ │ ├── mocks.js
│ │ │ │ └── upstream-author-bff
│ │ │ │ │ └── e2e.test.js
│ │ │ └── unit
│ │ │ │ └── utils
│ │ │ │ └── index.test.js
│ │ ├── .npmrc-conf
│ │ ├── .gitignore
│ │ ├── fixtures
│ │ │ ├── customer-frontend
│ │ │ │ └── get-thing0
│ │ │ └── dynamodb.us-east-1.amazonaws.com-443
│ │ │ │ └── save-thing0
│ │ ├── .editorconfig
│ │ ├── .nycrc
│ │ ├── .babelrc
│ │ └── src
│ │ │ └── get
│ │ │ └── index.js
│ ├── author-frontend
│ │ ├── .gitignore
│ │ ├── package.json
│ │ └── fixtures
│ │ │ └── 0.0.0.0-3001
│ │ │ ├── get-thing0
│ │ │ └── save-thing0
│ └── customer-frontend
│ │ ├── .gitignore
│ │ ├── package.json
│ │ └── fixtures
│ │ └── 0.0.0.0-3001
│ │ └── get-thing0
├── contract-testing-async
│ ├── downstream
│ │ ├── .eslintignore
│ │ ├── test
│ │ │ ├── helper.js
│ │ │ ├── int
│ │ │ │ ├── mocks.js
│ │ │ │ └── upstream-provider-y
│ │ │ │ │ └── contract.test.js
│ │ │ └── unit
│ │ │ │ └── utils
│ │ │ │ └── index.test.js
│ │ ├── .npmrc-conf
│ │ ├── .gitignore
│ │ ├── .editorconfig
│ │ ├── .nycrc
│ │ ├── .babelrc
│ │ ├── src
│ │ │ └── get
│ │ │ │ └── index.js
│ │ └── fixtures
│ │ │ └── dynamodb.us-east-1.amazonaws.com-443
│ │ │ └── save
│ ├── upstream
│ │ ├── .eslintignore
│ │ ├── test
│ │ │ ├── helper.js
│ │ │ ├── int
│ │ │ │ ├── mocks.js
│ │ │ │ └── save
│ │ │ │ │ └── index.test.js
│ │ │ └── unit
│ │ │ │ └── utils
│ │ │ │ └── index.test.js
│ │ ├── .npmrc-conf
│ │ ├── .gitignore
│ │ ├── .editorconfig
│ │ ├── .nycrc
│ │ ├── .babelrc
│ │ ├── src
│ │ │ └── connector
│ │ │ │ └── stream.js
│ │ └── fixtures
│ │ │ └── dynamodb.us-east-1.amazonaws.com-443
│ │ │ └── save
│ └── README.md
└── README.md
├── ch1
├── create-function
│ ├── .gitignore
│ ├── serverless.yml
│ ├── handler.js
│ ├── package.json
│ └── README.md
├── create-stack
│ ├── .gitignore
│ ├── serverless.yml
│ ├── README.md
│ └── package.json
├── event-stream
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── create-api-gateway
│ ├── .gitignore
│ ├── serverless.yml
│ ├── package.json
│ ├── handler.js
│ └── README.md
├── create-stream-processor
│ ├── .gitignore
│ ├── serverless.yml
│ ├── package.json
│ ├── README.md
│ └── handler.js
├── deploy-spa
│ ├── .gitignore
│ ├── src
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── App.test.js
│ │ ├── App.css
│ │ └── App.js
│ ├── public
│ │ ├── favicon.ico
│ │ └── manifest.json
│ ├── README.md
│ └── package.json
└── README.md
├── ch7
├── custom-metrics
│ ├── .gitignore
│ ├── README.md
│ ├── serverless.yml
│ ├── package.json
│ └── handler.js
├── datadog-account
│ ├── .gitignore
│ ├── handler.js
│ ├── package.json
│ └── README.md
├── event-metrics
│ ├── .gitignore
│ ├── README.md
│ └── package.json
├── synthetics
│ ├── .gitignore
│ ├── src
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── authenticate
│ │ │ └── index.js
│ │ ├── App.test.js
│ │ └── Home.css
│ ├── public
│ │ ├── favicon.ico
│ │ └── manifest.json
│ ├── serverless.yml
│ ├── README.md
│ └── package.json
└── README.md
├── ch8
├── handling-faults
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── idempotence-es
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── timeout-retry
│ ├── .gitignore
│ ├── package.json
│ ├── README.md
│ └── handler.js
├── resubmitting-faults
│ ├── .gitignore
│ ├── cli
│ │ ├── serverless.yml
│ │ ├── index.js
│ │ └── package.json
│ ├── simulator
│ │ └── package.json
│ └── monitor
│ │ └── package.json
├── backpressure-ratelimit
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── idempotence-inverse-oplock
│ ├── .gitignore
│ ├── package.json
│ └── README.md
└── README.md
├── ch9
├── cache-control
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── frp-batching
│ ├── .gitignore
│ ├── README.md
│ └── package.json
├── frp-grouping
│ ├── .gitignore
│ ├── README.md
│ └── package.json
├── dynamodb-autoscaling
│ ├── .gitignore
│ ├── README.md
│ └── package.json
├── frp-async-non-blocking-io
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── session-consistency
│ ├── service
│ │ ├── .gitignore
│ │ ├── schema
│ │ │ ├── thing
│ │ │ │ ├── index.js
│ │ │ │ ├── resolvers.js
│ │ │ │ └── typedefs.js
│ │ │ └── index.js
│ │ └── package.json
│ └── spa
│ │ ├── .gitignore
│ │ ├── src
│ │ ├── index.css
│ │ ├── App.test.js
│ │ ├── App.css
│ │ └── index.js
│ │ ├── public
│ │ ├── favicon.ico
│ │ └── manifest.json
│ │ └── package.json
├── tuning-faas
│ ├── .gitignore
│ ├── README.md
│ ├── src
│ │ ├── connector
│ │ │ └── stream.js
│ │ └── get
│ │ │ └── index.js
│ └── .babelrc
└── README.md
└── ch10
├── regional-failover
├── .gitignore
├── check
│ ├── handler.js
│ └── package.json
└── service
│ ├── package.json
│ └── handler.js
├── dynamodb-global-table
├── .gitignore
└── package.json
├── latency-based-routing
├── .gitignore
├── package.json
├── handler.js
└── README.md
├── regional-health-check
├── .gitignore
├── package.json
└── README.md
├── round-robin-replication
├── .gitignore
├── includes.yml
└── package.json
└── README.md
/ch4/cdn-site/dist/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/ch11/azure/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch11/gcp/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch3/saga/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch5/dr/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch5/waf/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch2/event-first/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch3/esg-inbound/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch4/cdn-json/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch4/cdn-lambda/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch4/cdn-service/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch5/graphql-jwt/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch5/jwt-filter/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch5/ssl-cert/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch6/pipeline/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch1/create-function/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch1/create-stack/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch1/event-stream/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch2/data-lake-es/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch2/data-lake-s3/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch2/db-first-cognito/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch2/replaying-events/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch3/bff-graphql-crud/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch3/bff-rest-search/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch3/esg-outbound/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch3/esg-sqs-inbound/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch4/cdn-invalidate/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch4/cdn-site/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
5 |
--------------------------------------------------------------------------------
/ch5/account-as-code/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch5/cognito-pool/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch7/custom-metrics/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch7/datadog-account/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch7/event-metrics/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch8/handling-faults/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch8/idempotence-es/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch8/timeout-retry/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch9/cache-control/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch9/frp-batching/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch9/frp-grouping/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch1/create-api-gateway/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch10/regional-failover/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch2/bi-directional-sync/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch2/db-first-dynamodb/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch2/materialized-view-es/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch2/materialized-view-s3/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch2/micro-event-store/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch3/bff-rest-analytics/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch3/event-orchestration/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch5/cognito-authorizer/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch5/custom-authorizer/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch5/envelope-encryption/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch6/unit-testing/.eslintignore:
--------------------------------------------------------------------------------
1 | tools/
2 | lib/
3 | coverage/
4 | webpack.config.js
5 |
--------------------------------------------------------------------------------
/ch8/resubmitting-faults/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch8/resubmitting-faults/cli/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-resubmitting-faults-cli
2 |
--------------------------------------------------------------------------------
/ch9/dynamodb-autoscaling/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch1/create-stream-processor/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch1/deploy-spa/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build
3 | .serverless
4 | .DS_Store
5 | *.log
6 |
--------------------------------------------------------------------------------
/ch10/dynamodb-global-table/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch10/latency-based-routing/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch10/regional-health-check/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch10/round-robin-replication/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch2/materialized-view-cognito/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch2/materialized-view-dynamodb/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch4/cdn-dns/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build
3 | .serverless
4 | .DS_Store
5 | *.log
6 |
--------------------------------------------------------------------------------
/ch4/cdn-spa/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build
3 | .serverless
4 | .DS_Store
5 | *.log
6 |
--------------------------------------------------------------------------------
/ch6/integration-testing/.eslintignore:
--------------------------------------------------------------------------------
1 | tools/
2 | lib/
3 | coverage/
4 | webpack.config.js
5 |
--------------------------------------------------------------------------------
/ch7/synthetics/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build
3 | .serverless
4 | .DS_Store
5 | *.log
6 |
--------------------------------------------------------------------------------
/ch8/backpressure-ratelimit/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch8/idempotence-inverse-oplock/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch9/frp-async-non-blocking-io/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch1/create-stack/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-create-stack
2 |
3 | provider:
4 | name: aws
5 |
--------------------------------------------------------------------------------
/ch5/cognito-signin/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build
3 | .serverless
4 | .DS_Store
5 | *.log
6 |
--------------------------------------------------------------------------------
/ch6/feature-flag/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build
3 | .serverless
4 | .DS_Store
5 | *.log
6 |
--------------------------------------------------------------------------------
/ch9/session-consistency/service/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .serverless
3 | .DS_Store
4 | *.log
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/.eslintignore:
--------------------------------------------------------------------------------
1 | tools/
2 | lib/
3 | coverage/
4 | webpack.config.js
5 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/.eslintignore:
--------------------------------------------------------------------------------
1 | tools/
2 | lib/
3 | coverage/
4 | webpack.config.js
5 |
--------------------------------------------------------------------------------
/ch4/cdn-dns/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/ch4/cdn-spa/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/downstream/.eslintignore:
--------------------------------------------------------------------------------
1 | tools/
2 | lib/
3 | coverage/
4 | webpack.config.js
5 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/upstream/.eslintignore:
--------------------------------------------------------------------------------
1 | tools/
2 | lib/
3 | coverage/
4 | webpack.config.js
5 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-bff/.eslintignore:
--------------------------------------------------------------------------------
1 | tools/
2 | lib/
3 | coverage/
4 | webpack.config.js
5 |
--------------------------------------------------------------------------------
/ch9/session-consistency/spa/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build
3 | .serverless
4 | .DS_Store
5 | *.log
6 |
--------------------------------------------------------------------------------
/ch1/deploy-spa/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/ch6/feature-flag/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/ch7/synthetics/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/ch5/cognito-signin/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/ch3/saga/data/order.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "33333333-7777-1111-1111-111111111111",
3 | "sku": "1",
4 | "quantity": 1
5 | }
--------------------------------------------------------------------------------
/ch4/cdn-site/content/posts/fourth-post.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Fourth post"
3 | date: "2017-01-04"
4 | ---
5 |
6 | Another post
7 |
--------------------------------------------------------------------------------
/ch4/cdn-site/content/posts/second-post.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Second post"
3 | date: "2017-01-02"
4 | ---
5 |
6 | Another post
7 |
--------------------------------------------------------------------------------
/ch4/cdn-site/dist/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DanteInc/js-cloud-native-cookbook/HEAD/ch4/cdn-site/dist/favicon.ico
--------------------------------------------------------------------------------
/ch9/session-consistency/spa/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/ch4/cdn-dns/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DanteInc/js-cloud-native-cookbook/HEAD/ch4/cdn-dns/public/favicon.ico
--------------------------------------------------------------------------------
/ch4/cdn-spa/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DanteInc/js-cloud-native-cookbook/HEAD/ch4/cdn-spa/public/favicon.ico
--------------------------------------------------------------------------------
/ch6/unit-testing/test/helper.js:
--------------------------------------------------------------------------------
1 | import chai from 'chai';
2 | import sinonChai from 'sinon-chai';
3 |
4 | chai.use(sinonChai);
5 |
--------------------------------------------------------------------------------
/ch1/deploy-spa/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DanteInc/js-cloud-native-cookbook/HEAD/ch1/deploy-spa/public/favicon.ico
--------------------------------------------------------------------------------
/ch4/cdn-site/content/posts/third-post.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Third post"
3 | date: "2017-01-03"
4 | ---
5 |
6 | Another postttttttttttt
7 |
--------------------------------------------------------------------------------
/ch6/integration-testing/test/helper.js:
--------------------------------------------------------------------------------
1 | import chai from 'chai';
2 | import sinonChai from 'sinon-chai';
3 |
4 | chai.use(sinonChai);
5 |
--------------------------------------------------------------------------------
/ch7/synthetics/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DanteInc/js-cloud-native-cookbook/HEAD/ch7/synthetics/public/favicon.ico
--------------------------------------------------------------------------------
/ch2/replaying-events/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | require('yargs')
3 | .commandDir('lib')
4 | .demandCommand()
5 | .help()
6 | .argv
--------------------------------------------------------------------------------
/ch5/cognito-signin/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DanteInc/js-cloud-native-cookbook/HEAD/ch5/cognito-signin/public/favicon.ico
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/test/helper.js:
--------------------------------------------------------------------------------
1 | import chai from 'chai';
2 | import sinonChai from 'sinon-chai';
3 |
4 | chai.use(sinonChai);
5 |
--------------------------------------------------------------------------------
/ch6/feature-flag/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DanteInc/js-cloud-native-cookbook/HEAD/ch6/feature-flag/public/favicon.ico
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/test/helper.js:
--------------------------------------------------------------------------------
1 | import chai from 'chai';
2 | import sinonChai from 'sinon-chai';
3 |
4 | chai.use(sinonChai);
5 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/downstream/test/helper.js:
--------------------------------------------------------------------------------
1 | import chai from 'chai';
2 | import sinonChai from 'sinon-chai';
3 |
4 | chai.use(sinonChai);
5 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/upstream/test/helper.js:
--------------------------------------------------------------------------------
1 | import chai from 'chai';
2 | import sinonChai from 'sinon-chai';
3 |
4 | chai.use(sinonChai);
5 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-bff/test/helper.js:
--------------------------------------------------------------------------------
1 | import chai from 'chai';
2 | import sinonChai from 'sinon-chai';
3 |
4 | chai.use(sinonChai);
5 |
--------------------------------------------------------------------------------
/ch8/resubmitting-faults/cli/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | require('yargs')
3 | .commandDir('lib')
4 | .demandCommand()
5 | .help()
6 | .argv
--------------------------------------------------------------------------------
/ch6/pipeline/.npmrc-conf:
--------------------------------------------------------------------------------
1 | @my:registry=https://npm.my.example.com/
2 | //npm.my.example.com/:_authToken=${NPM_TOKEN}
3 | //npm.my.example.com/:always-auth=true
4 |
--------------------------------------------------------------------------------
/ch9/session-consistency/spa/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DanteInc/js-cloud-native-cookbook/HEAD/ch9/session-consistency/spa/public/favicon.ico
--------------------------------------------------------------------------------
/ch11/README.md:
--------------------------------------------------------------------------------
1 | # Welcoming Polycloud
2 |
3 | 1. [Creating a service with Google Cloud Functions](./gcp)
4 | 2. [Creating a service with Azure Functions](./azure)
5 |
--------------------------------------------------------------------------------
/ch4/cdn-site/dist/phenomic/content/posts/item/third-post.json:
--------------------------------------------------------------------------------
1 | {"filename":"third-post.md","title":"Third post","date":"2017-01-03","body":{"t":"p","c":["Another post"]}}
--------------------------------------------------------------------------------
/ch6/unit-testing/.npmrc-conf:
--------------------------------------------------------------------------------
1 | @my:registry=https://npm.my.example.com/
2 | //npm.my.example.com/:_authToken=${NPM_TOKEN}
3 | //npm.my.example.com/:always-auth=true
4 |
--------------------------------------------------------------------------------
/ch4/cdn-site/dist/phenomic/content/posts/item/fourth-post.json:
--------------------------------------------------------------------------------
1 | {"filename":"fourth-post.md","title":"Fourth post","date":"2017-01-04","body":{"t":"p","c":["Another post"]}}
--------------------------------------------------------------------------------
/ch4/cdn-site/dist/phenomic/content/posts/item/second-post.json:
--------------------------------------------------------------------------------
1 | {"filename":"second-post.md","title":"Second post","date":"2017-01-02","body":{"t":"p","c":["Another post"]}}
--------------------------------------------------------------------------------
/ch6/integration-testing/.npmrc-conf:
--------------------------------------------------------------------------------
1 | @my:registry=https://npm.my.example.com/
2 | //npm.my.example.com/:_authToken=${NPM_TOKEN}
3 | //npm.my.example.com/:always-auth=true
4 |
--------------------------------------------------------------------------------
/ch6/unit-testing/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | .nyc_output
4 | .serverless
5 | .webpack
6 | *.log
7 | .vscode
8 | .eslintcache
9 | .DS_Store
10 |
11 |
--------------------------------------------------------------------------------
/ch7/datadog-account/handler.js:
--------------------------------------------------------------------------------
1 | module.exports.hello = (event, context, callback) => {
2 | console.log('event: %j', event);
3 | callback(null, 'success');
4 | };
5 |
--------------------------------------------------------------------------------
/ch9/tuning-faas/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | .nyc_output
4 | .serverless
5 | .webpack
6 | *.log
7 | .vscode
8 | .eslintcache
9 | .DS_Store
10 |
11 |
--------------------------------------------------------------------------------
/ch6/integration-testing/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | .nyc_output
4 | .serverless
5 | .webpack
6 | *.log
7 | .vscode
8 | .eslintcache
9 | .DS_Store
10 |
11 |
--------------------------------------------------------------------------------
/ch2/replaying-events/handler.js:
--------------------------------------------------------------------------------
1 | module.exports.listener = (event, context, callback) => {
2 | console.log('event: %j', event);
3 |
4 | callback(null, 'success');
5 | };
6 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/.npmrc-conf:
--------------------------------------------------------------------------------
1 | @my:registry=https://npm.my.example.com/
2 | //npm.my.example.com/:_authToken=${NPM_TOKEN}
3 | //npm.my.example.com/:always-auth=true
4 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/.npmrc-conf:
--------------------------------------------------------------------------------
1 | @my:registry=https://npm.my.example.com/
2 | //npm.my.example.com/:_authToken=${NPM_TOKEN}
3 | //npm.my.example.com/:always-auth=true
4 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/downstream/.npmrc-conf:
--------------------------------------------------------------------------------
1 | @my:registry=https://npm.my.example.com/
2 | //npm.my.example.com/:_authToken=${NPM_TOKEN}
3 | //npm.my.example.com/:always-auth=true
4 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/upstream/.npmrc-conf:
--------------------------------------------------------------------------------
1 | @my:registry=https://npm.my.example.com/
2 | //npm.my.example.com/:_authToken=${NPM_TOKEN}
3 | //npm.my.example.com/:always-auth=true
4 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | .nyc_output
4 | .serverless
5 | .webpack
6 | *.log
7 | .vscode
8 | .eslintcache
9 | .DS_Store
10 |
11 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | .nyc_output
4 | .serverless
5 | .webpack
6 | *.log
7 | .vscode
8 | .eslintcache
9 | .DS_Store
10 |
11 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-bff/.npmrc-conf:
--------------------------------------------------------------------------------
1 | @my:registry=https://npm.my.example.com/
2 | //npm.my.example.com/:_authToken=${NPM_TOKEN}
3 | //npm.my.example.com/:always-auth=true
4 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/downstream/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | .nyc_output
4 | .serverless
5 | .webpack
6 | *.log
7 | .vscode
8 | .eslintcache
9 | .DS_Store
10 |
11 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/upstream/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | .nyc_output
4 | .serverless
5 | .webpack
6 | *.log
7 | .vscode
8 | .eslintcache
9 | .DS_Store
10 |
11 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | .nyc_output
4 | .serverless
5 | .webpack
6 | *.log
7 | .vscode
8 | .eslintcache
9 | .DS_Store
10 |
11 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-frontend/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | .nyc_output
4 | .serverless
5 | .webpack
6 | *.log
7 | .vscode
8 | .eslintcache
9 | .DS_Store
10 |
11 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-bff/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | .nyc_output
4 | .serverless
5 | .webpack
6 | *.log
7 | .vscode
8 | .eslintcache
9 | .DS_Store
10 |
11 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-frontend/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | .nyc_output
4 | .serverless
5 | .webpack
6 | *.log
7 | .vscode
8 | .eslintcache
9 | .DS_Store
10 |
11 |
--------------------------------------------------------------------------------
/ch5/graphql-jwt/schema/thing/index.js:
--------------------------------------------------------------------------------
1 | module.exports.thingTypeDefs = require('./typedefs');
2 | module.exports.thingResolvers = require('./resolvers');
3 | module.exports.Thing = require('./model');
4 |
--------------------------------------------------------------------------------
/ch3/bff-graphql-crud/schema/thing/index.js:
--------------------------------------------------------------------------------
1 | module.exports.thingTypeDefs = require('./typedefs');
2 | module.exports.thingResolvers = require('./resolvers');
3 | module.exports.Thing = require('./model');
4 |
--------------------------------------------------------------------------------
/ch5/waf/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | JavaScript Cloud Native Development Cookbook!
5 | Your WAF allowed you to successfully access this page!
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ch2/replaying-events/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-replaying-events
2 |
3 | provider:
4 | name: aws
5 | runtime: nodejs8.10
6 |
7 | functions:
8 | listener:
9 | handler: handler.listener
10 |
--------------------------------------------------------------------------------
/ch5/ssl-cert/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | JavaScript Cloud Native Development Cookbook!
5 | Your secure single page application loaded successfully!
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ch6/integration-testing/test/int/mocks.js:
--------------------------------------------------------------------------------
1 | import * as sinon from 'sinon';
2 | import * as utils from '../../src/utils';
3 |
4 | sinon.stub(utils, 'uuidv4')
5 | .returns('00000000-0000-0000-0000-000000000000');
6 |
--------------------------------------------------------------------------------
/ch9/session-consistency/service/schema/thing/index.js:
--------------------------------------------------------------------------------
1 | module.exports.thingTypeDefs = require('./typedefs');
2 | module.exports.thingResolvers = require('./resolvers');
3 | module.exports.Thing = require('./model');
4 |
--------------------------------------------------------------------------------
/ch1/deploy-spa/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 |
6 | ReactDOM.render(, document.getElementById('root'));
7 |
--------------------------------------------------------------------------------
/ch5/cognito-signin/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 |
6 | ReactDOM.render(, document.getElementById('root'));
7 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/test/int/mocks.js:
--------------------------------------------------------------------------------
1 | import * as sinon from 'sinon';
2 | import * as utils from '../../src/utils';
3 |
4 | sinon.stub(utils, 'uuidv4')
5 | .returns('00000000-0000-0000-0000-000000000000');
6 |
--------------------------------------------------------------------------------
/ch6/feature-flag/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 |
6 | ReactDOM.render(, document.getElementById('root'));
7 |
--------------------------------------------------------------------------------
/ch7/synthetics/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 |
6 | ReactDOM.render(, document.getElementById('root'));
7 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/upstream/test/int/mocks.js:
--------------------------------------------------------------------------------
1 | import * as sinon from 'sinon';
2 | import * as utils from '../../src/utils';
3 |
4 | sinon.stub(utils, 'uuidv4')
5 | .returns('00000000-0000-0000-0000-000000000000');
6 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/test/int/mocks.js:
--------------------------------------------------------------------------------
1 | import * as sinon from 'sinon';
2 | import * as utils from '../../src/utils';
3 |
4 | sinon.stub(utils, 'uuidv4')
5 | .returns('00000000-0000-0000-0000-000000000000');
6 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-bff/test/int/mocks.js:
--------------------------------------------------------------------------------
1 | import * as sinon from 'sinon';
2 | import * as utils from '../../src/utils';
3 |
4 | sinon.stub(utils, 'uuidv4')
5 | .returns('00000000-0000-0000-0000-000000000000');
6 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/downstream/test/int/mocks.js:
--------------------------------------------------------------------------------
1 | import * as sinon from 'sinon';
2 | import * as utils from '../../src/utils';
3 |
4 | sinon.stub(utils, 'uuidv4')
5 | .returns('00000000-0000-0000-0000-000000000000');
6 |
--------------------------------------------------------------------------------
/ch1/create-function/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-create-function
2 |
3 | provider:
4 | name: aws
5 | runtime: nodejs8.10
6 | environment:
7 | V1: value1
8 |
9 | functions:
10 | hello:
11 | handler: handler.hello
12 |
--------------------------------------------------------------------------------
/ch1/create-function/handler.js:
--------------------------------------------------------------------------------
1 | module.exports.hello = (event, context, callback) => {
2 | console.log('event: %j', event);
3 | console.log('context: %j', context);
4 | console.log('env: %j', process.env);
5 |
6 | callback(null, 'success');
7 | };
8 |
--------------------------------------------------------------------------------
/ch3/event-orchestration/data/order.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "33333333-6666-0000-1111-111111111111",
3 | "type": "order-submitted",
4 | "order": {
5 | "id": "33333333-6666-1111-1111-111111111111",
6 | "sku": "1",
7 | "quantity": 1
8 | }
9 | }
--------------------------------------------------------------------------------
/ch6/feature-flag/src/authenticate/index.js:
--------------------------------------------------------------------------------
1 | export { default as CognitoSecurity } from './auth';
2 | export { default as withAuth } from './withAuth';
3 | export { default as SecureRoute } from './secureRoute';
4 | export { default as ImplicitCallback } from './implicitCallback';
5 |
--------------------------------------------------------------------------------
/ch6/unit-testing/README.md:
--------------------------------------------------------------------------------
1 | # Writing unit tests
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch6/unit-testing --path cncb-unit-testing
5 | 2. cd cncb-unit-testing
6 | 3. npm install
7 | 4. npm test
8 |
--------------------------------------------------------------------------------
/ch7/synthetics/src/authenticate/index.js:
--------------------------------------------------------------------------------
1 | export { default as CognitoSecurity } from './auth';
2 | export { default as withAuth } from './withAuth';
3 | export { default as SecureRoute } from './secureRoute';
4 | export { default as ImplicitCallback } from './implicitCallback';
5 |
--------------------------------------------------------------------------------
/ch5/cognito-signin/src/authenticate/index.js:
--------------------------------------------------------------------------------
1 | export { default as CognitoSecurity } from './auth';
2 | export { default as withAuth } from './withAuth';
3 | export { default as SecureRoute } from './secureRoute';
4 | export { default as ImplicitCallback } from './implicitCallback';
5 |
--------------------------------------------------------------------------------
/ch6/unit-testing/test/unit/utils/index.test.js:
--------------------------------------------------------------------------------
1 | import 'mocha';
2 | import { expect } from 'chai';
3 | import { uuidv4 } from '../../../src/utils';
4 |
5 | describe('utils/index.js', () => {
6 | it('should create a uuid', () => {
7 | expect(uuidv4()).to.not.equal(null);
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/ch4/cdn-dns/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import registerServiceWorker from './registerServiceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 | registerServiceWorker();
9 |
--------------------------------------------------------------------------------
/ch4/cdn-spa/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import registerServiceWorker from './registerServiceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 | registerServiceWorker();
9 |
--------------------------------------------------------------------------------
/ch7/README.md:
--------------------------------------------------------------------------------
1 | # Optimizing Observability
2 |
3 | 1. [Monitoring a cloud-native system](./datadog-account)
4 | 2. [Implementing custom metrics](./custom-metrics)
5 | 3. [Monitoring domain events](./event-metrics)
6 | 4. [Creating alerts](README.md)
7 | 5. [Creating synthetic transaction tests](./synthetics)
8 |
--------------------------------------------------------------------------------
/ch6/integration-testing/test/unit/utils/index.test.js:
--------------------------------------------------------------------------------
1 | import 'mocha';
2 | import { expect } from 'chai';
3 | import { uuidv4 } from '../../../src/utils';
4 |
5 | describe('utils/index.js', () => {
6 | it('should create a uuid', () => {
7 | expect(uuidv4()).to.not.equal(null);
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/ch4/cdn-dns/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | ReactDOM.unmountComponentAtNode(div);
9 | });
10 |
--------------------------------------------------------------------------------
/ch4/cdn-spa/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | ReactDOM.unmountComponentAtNode(div);
9 | });
10 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/test/unit/utils/index.test.js:
--------------------------------------------------------------------------------
1 | import 'mocha';
2 | import { expect } from 'chai';
3 | import { uuidv4 } from '../../../src/utils';
4 |
5 | describe('utils/index.js', () => {
6 | it('should create a uuid', () => {
7 | expect(uuidv4()).to.not.equal(null);
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/ch1/create-api-gateway/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-create-api-gateway
2 |
3 | provider:
4 | name: aws
5 | runtime: nodejs8.10
6 |
7 | functions:
8 | hello:
9 | handler: handler.hello
10 | events:
11 | - http:
12 | path: hello
13 | method: get
14 | cors: true
15 |
--------------------------------------------------------------------------------
/ch1/deploy-spa/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | ReactDOM.unmountComponentAtNode(div);
9 | });
10 |
--------------------------------------------------------------------------------
/ch5/cognito-signin/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | ReactDOM.unmountComponentAtNode(div);
9 | });
10 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/upstream/test/unit/utils/index.test.js:
--------------------------------------------------------------------------------
1 | import 'mocha';
2 | import { expect } from 'chai';
3 | import { uuidv4 } from '../../../src/utils';
4 |
5 | describe('utils/index.js', () => {
6 | it('should create a uuid', () => {
7 | expect(uuidv4()).to.not.equal(null);
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/ch6/feature-flag/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | ReactDOM.unmountComponentAtNode(div);
9 | });
10 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/test/unit/utils/index.test.js:
--------------------------------------------------------------------------------
1 | import 'mocha';
2 | import { expect } from 'chai';
3 | import { uuidv4 } from '../../../src/utils';
4 |
5 | describe('utils/index.js', () => {
6 | it('should create a uuid', () => {
7 | expect(uuidv4()).to.not.equal(null);
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-bff/test/unit/utils/index.test.js:
--------------------------------------------------------------------------------
1 | import 'mocha';
2 | import { expect } from 'chai';
3 | import { uuidv4 } from '../../../src/utils';
4 |
5 | describe('utils/index.js', () => {
6 | it('should create a uuid', () => {
7 | expect(uuidv4()).to.not.equal(null);
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/ch7/synthetics/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | ReactDOM.unmountComponentAtNode(div);
9 | });
10 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/downstream/test/unit/utils/index.test.js:
--------------------------------------------------------------------------------
1 | import 'mocha';
2 | import { expect } from 'chai';
3 | import { uuidv4 } from '../../../src/utils';
4 |
5 | describe('utils/index.js', () => {
6 | it('should create a uuid', () => {
7 | expect(uuidv4()).to.not.equal(null);
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/ch4/cdn-site/dist/phenomic/content/posts/by-default/1/desc/date/limit-2.json:
--------------------------------------------------------------------------------
1 | {"previousPageIsFirst":true,"next":"dGhpcmQtcG9zdA==","list":[{"id":"fifth-post","filename":"fifth-post.md","title":"Fifth post","date":"2017-01-05","layout":"hero"},{"id":"fourth-post","filename":"fourth-post.md","title":"Fourth post","date":"2017-01-04"}]}
--------------------------------------------------------------------------------
/ch9/session-consistency/spa/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | ReactDOM.unmountComponentAtNode(div);
9 | });
10 |
--------------------------------------------------------------------------------
/ch11/gcp/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.hello = (request, response) => {
4 | console.log('env: %j', process.env);
5 |
6 | response.status(200).send('JavaScript Cloud Native Development Cookbook! Your function executed successfully!');
7 | };
8 |
9 | exports.trigger = (event, callback) => {
10 | callback();
11 | };
12 |
--------------------------------------------------------------------------------
/ch4/cdn-site/dist/phenomic/content/posts/by-default/1/desc/date/limit-2/after-Zmlyc3QtcG9zdA==.json:
--------------------------------------------------------------------------------
1 | {"previousPageIsFirst":false,"previous":"dGhpcmQtcG9zdA==","list":[{"id":"first-post","filename":"first-post.md","title":"First post","headings":[{"level":1,"text":"This is a Markdown file","id":"this-is-a-markdown-file"}],"date":"2017-01-01"}]}
--------------------------------------------------------------------------------
/ch6/pipeline/README.md:
--------------------------------------------------------------------------------
1 | # Creating a CI/CD pipeline
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch6/pipeline --path cncb-pipeline
5 | 2. cd cncb-pipeline
6 | 3. npm install
7 | 4. npm test
8 | 6. npm run dp:lcl -- -s $MY_STAGE
9 | 7. npm run rm:lcl -- -s $MY_STAGE
--------------------------------------------------------------------------------
/ch1/create-stack/README.md:
--------------------------------------------------------------------------------
1 | # Creating a stack
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch1/create-stack --path cncb-create-stack
5 | 2. cd cncb-create-stack
6 | 3. npm install
7 | 4. npm test
8 | 6. npm run dp:lcl -- -s $MY_STAGE
9 | 7. npm run rm:lcl -- -s $MY_STAGE
--------------------------------------------------------------------------------
/ch6/pipeline/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-pipeline
2 |
3 | provider:
4 | name: aws
5 | # cfnRole: arn:aws:iam::${self:custom.accounts.${opt:acct}.accountNumber}:role/${opt:stage}-cfnRole
6 |
7 | custom:
8 | accounts:
9 | dev:
10 | accountNumber: 123456789012
11 | prod:
12 | accountNumber: 210987654321
13 |
14 |
--------------------------------------------------------------------------------
/ch4/cdn-site/dist/phenomic/content/posts/by-default/1/desc/date/limit-2/after-ZmlmdGgtcG9zdA==.json:
--------------------------------------------------------------------------------
1 | {"previousPageIsFirst":true,"next":"dGhpcmQtcG9zdA==","list":[{"id":"fifth-post","filename":"fifth-post.md","title":"Fifth post","date":"2017-01-05","layout":"hero"},{"id":"fourth-post","filename":"fourth-post.md","title":"Fourth post","date":"2017-01-04"}]}
--------------------------------------------------------------------------------
/ch3/esg-inbound/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-esg-inbound",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | }
13 | }
--------------------------------------------------------------------------------
/ch6/integration-testing/README.md:
--------------------------------------------------------------------------------
1 | # Writing integration tests
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch6/integration-testing --path cncb-integration-testing
5 | 2. cd cncb-integration-testing
6 | 3. npm install
7 | 4. npm test
8 | 5. DEBUG=replay REPLAY=record npm run test:int
9 |
--------------------------------------------------------------------------------
/ch4/cdn-json/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-cdn-json",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ch4/cdn-site/dist/phenomic/content/posts/by-default/1/desc/date/limit-2/after-Zm91cnRoLXBvc3Q=.json:
--------------------------------------------------------------------------------
1 | {"previousPageIsFirst":true,"previous":"ZmlmdGgtcG9zdA==","next":"c2Vjb25kLXBvc3Q=","list":[{"id":"fourth-post","filename":"fourth-post.md","title":"Fourth post","date":"2017-01-04"},{"id":"third-post","filename":"third-post.md","title":"Third post","date":"2017-01-03"}]}
--------------------------------------------------------------------------------
/ch4/cdn-site/dist/phenomic/content/posts/by-default/1/desc/date/limit-2/after-dGhpcmQtcG9zdA==.json:
--------------------------------------------------------------------------------
1 | {"previousPageIsFirst":true,"previous":"ZmlmdGgtcG9zdA==","next":"Zmlyc3QtcG9zdA==","list":[{"id":"third-post","filename":"third-post.md","title":"Third post","date":"2017-01-03"},{"id":"second-post","filename":"second-post.md","title":"Second post","date":"2017-01-02"}]}
--------------------------------------------------------------------------------
/ch1/create-function/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-create-function",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | }
13 | }
--------------------------------------------------------------------------------
/ch1/create-stack/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-create-stack",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -v -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -v -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | }
13 | }
--------------------------------------------------------------------------------
/ch4/cdn-service/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-cdn-service",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ch5/cognito-authorizer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-cognito-authorizer",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | }
13 | }
--------------------------------------------------------------------------------
/ch9/tuning-faas/README.md:
--------------------------------------------------------------------------------
1 | # Tuning function-as-a-service
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch9/tuning-faas --path cncb-tuning-faas
5 | 2. cd cncb-tuning-faas
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. npm run rm:lcl -- -s $MY_STAGE
10 |
--------------------------------------------------------------------------------
/ch1/create-api-gateway/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-create-api-gateway",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | }
13 | }
--------------------------------------------------------------------------------
/ch11/azure/handler.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports.hello = function (context) {
4 | context.log('context: %j', context);
5 | context.log('env: %j', process.env);
6 |
7 | context.res = {
8 | status: 200,
9 | body: 'JavaScript Cloud Native Development Cookbook! Your function executed successfully!',
10 | };
11 |
12 | context.done();
13 | };
14 |
--------------------------------------------------------------------------------
/ch5/account-as-code/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-account-as-code",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ch7/datadog-account/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-datadog-account",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ch9/cache-control/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-cache-control",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ch5/waf/README.md:
--------------------------------------------------------------------------------
1 | # Configuring a web application firewall
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch5/waf --path cncb-waf
5 | 2. cd cncb-waf
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. Access cdn endpoint
10 | 7. npm run rm:lcl -- -s $MY_STAGE
11 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/README.md:
--------------------------------------------------------------------------------
1 | # Writing contract tests for a synchronous api
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch6/contract-testing-sync --path cncb-contract-testing-sync
5 | 2. cd cncb-contract-testing-sync
6 | 3. npm install
7 | 4. npm test
8 | 5. DEBUG=replay REPLAY=record npm run test:int
9 |
--------------------------------------------------------------------------------
/ch10/README.md:
--------------------------------------------------------------------------------
1 | # Deploying to Multiple Regions
2 |
3 | 1. [Implementing latency based routing](./latency-based-routing)
4 | 2. [Creating a regional health check](./regional-health-check)
5 | 3. [Triggering regional failover](./regional-failover)
6 | 4. [Implement regional replication with DynamoDB](./dynamodb-global-table)
7 | 5. [Implementing round robin replication](./round-robin-replication)
8 |
--------------------------------------------------------------------------------
/ch6/feature-flag/README.md:
--------------------------------------------------------------------------------
1 | # Leveraging feature flags
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch6/feature-flag --path cncb-feature-flag
5 | 2. cd cncb-feature-flag
6 | 3. npm install
7 | 4. Update src/configuration.js
8 | 5. npm start
9 | 6. Click Sign In and complete form
10 | 7. Note rendered data
11 |
--------------------------------------------------------------------------------
/ch4/cdn-site/content/posts/fifth-post.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Fifth post"
3 | date: "2017-01-05"
4 | layout: hero
5 | ---
6 |
7 | Another post that have a [link to the first one](../first-post/).
8 |
9 | An wrong link to [a post that does not exist](../unknown-post/) and another one
10 | to [a page that does not exist](/unknown-page/).
11 |
12 | Here is an [external link](http://phenomic.io).
13 |
--------------------------------------------------------------------------------
/ch5/cognito-pool/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-cognito-pool",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "lodash": "^4.17.10",
12 | "serverless": "1.26.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ch11/azure/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-azure",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r 'East US' -s test",
7 | "dp:lcl": "sls deploy -v -r 'East US'",
8 | "rm:lcl": "sls remove -v -r 'East US'"
9 | },
10 | "devDependencies": {
11 | "serverless": "^1.30.1",
12 | "serverless-azure-functions": "^0.6.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ch11/gcp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-gcp",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "test": "sls package -r us-east1 -s test",
7 | "dp:lcl": "sls deploy -v --r us-east1",
8 | "rm:lcl": "sls remove -r us-east1"
9 | },
10 | "devDependencies": {
11 | "serverless": "^1.30.1",
12 | "serverless-google-cloudfunctions": "^2.0.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ch1/deploy-spa/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/ch2/event-first/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-event-first",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | },
13 | "dependencies": {
14 | "uuid": "^3.2.1"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch4/cdn-dns/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/ch4/cdn-spa/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/ch5/jwt-filter/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-jwt-filter",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "dependencies": {
11 | "uuid": "^3.1.0"
12 | },
13 | "devDependencies": {
14 | "serverless": "1.26.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch7/synthetics/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/ch10/regional-failover/check/handler.js:
--------------------------------------------------------------------------------
1 | module.exports.check = (request, context, callback) => {
2 | callback(null, {
3 | statusCode: process.env.UNHEALTHY === 'true' ? 503 : 200,
4 | body: JSON.stringify({
5 | timestamp: Date.now(),
6 | region: process.env.AWS_REGION,
7 | }),
8 | headers: {
9 | 'Cache-Control': 'no-cache, no-store, must-revalidate',
10 | },
11 | });
12 | };
13 |
--------------------------------------------------------------------------------
/ch2/data-lake-s3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-data-lake-s3",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | },
13 | "dependencies": {
14 | "uuid": "^3.2.1"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch5/cognito-signin/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/ch5/ssl-cert/README.md:
--------------------------------------------------------------------------------
1 | # Creating an SSL certificate for encryption in transit
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch5/ssl-cert --path cncb-ssl-cert
5 | 2. cd cncb-ssl-cert
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. Access cdn endpoint
10 | 7. npm run rm:lcl -- -s $MY_STAGE
11 |
--------------------------------------------------------------------------------
/ch6/feature-flag/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/ch1/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Cloud-Native
2 |
3 | 1. [Creating a stack](./create-stack)
4 | 2. [Creating a function and working with metrics and logs](./create-function)
5 | 3. [Creating an event stream and publishing an event](./event-stream)
6 | 4. [Creating a stream processor](./create-stream-processor)
7 | 5. [Creating an API Gateway](./create-api-gateway)
8 | 6. [Deploying a single page application](./deploy-spa)
9 |
--------------------------------------------------------------------------------
/ch1/event-stream/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-event-stream",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | },
13 | "dependencies": {
14 | "uuid": "^3.2.1"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch4/cdn-lambda/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-cdn-lambda",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0",
12 | "serverless-plugin-cloudfront-lambda-edge": "^2.0.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ch4/cdn-site/dist/phenomic/content/posts/by-default/1/desc/date/limit-2/after-c2Vjb25kLXBvc3Q=.json:
--------------------------------------------------------------------------------
1 | {"previousPageIsFirst":false,"previous":"Zm91cnRoLXBvc3Q=","list":[{"id":"second-post","filename":"second-post.md","title":"Second post","date":"2017-01-02"},{"id":"first-post","filename":"first-post.md","title":"First post","headings":[{"level":1,"text":"This is a Markdown file","id":"this-is-a-markdown-file"}],"date":"2017-01-01"}]}
--------------------------------------------------------------------------------
/ch1/create-stream-processor/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-create-stream-processor
2 |
3 | provider:
4 | name: aws
5 | runtime: nodejs8.10
6 |
7 | functions:
8 | listener:
9 | handler: handler.listener
10 | events:
11 | - stream:
12 | type: kinesis
13 | arn: ${cf:cncb-event-stream-${opt:stage}.streamArn}
14 | batchSize: 100
15 | startingPosition: TRIM_HORIZON
16 |
--------------------------------------------------------------------------------
/ch3/esg-sqs-inbound/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-esg-sqs-inbound",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.32.0"
12 | },
13 | "dependencies": {
14 | "highland": "^2.13.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch5/dr/recovery-account/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-dr-recovery-account",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-west-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-west-1",
8 | "rm:lcl": "sls remove -r us-west-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0",
12 | "serverless-pseudo-parameters": "^1.6.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ch8/timeout-retry/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-timeout-retry",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "dependencies": {
11 | "uuid": "^3.1.0"
12 | },
13 | "devDependencies": {
14 | "serverless": "1.26.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch9/session-consistency/spa/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/ch3/saga/data/reservation.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "33333333-7777-0000-2222-111111111111",
3 | "type": "reservation-violation",
4 | "reservation": {
5 | "id": "33333333-7777-2222-1111-111111111111"
6 | },
7 | "context": {
8 | "order": {
9 | "id": "33333333-7777-1111-1111-111111111111",
10 | "sku": "1",
11 | "quanity": 1
12 | },
13 | "trigger": "33333333-7777-0000-1111-111111111111"
14 | }
15 | }
--------------------------------------------------------------------------------
/ch5/waf/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-waf",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0",
12 | "serverless-spa-config": "1.0.2",
13 | "serverless-spa-deploy": "1.0.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ch8/README.md:
--------------------------------------------------------------------------------
1 | # Designing for Failure
2 |
3 | 1. [Employing proper timeouts and retries](./timeout-retry)
4 | 2. [Implementing backpressure and rate limiting](./backpressure-ratelimit)
5 | 3. [Handling Faults](./handling-faults)
6 | 4. [Resubmitting fault events](./resubmitting-faults)
7 | 5. [Implementing idempotency with an inverse oplock](./idempotence-inverse-oplock)
8 | 6. [Implementing idempotency with event sourcing](./idempotence-es)
9 |
--------------------------------------------------------------------------------
/ch1/create-stream-processor/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-create-stream-processor",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | },
13 | "dependencies": {
14 | "highland": "^2.11.1"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch5/ssl-cert/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-ssl-cert",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0",
12 | "serverless-spa-config": "1.0.2",
13 | "serverless-spa-deploy": "1.0.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ch11/gcp/README.md:
--------------------------------------------------------------------------------
1 | # Creating a service in GCP
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch11/gcp --path cncb-gcp
5 | 2. cd cncb-gcp
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. curl -v https://us-east1-cncb-project.cloudfunctions.net/hello
10 | 7. sls logs -f hello -r us-east1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch3/event-orchestration/data/reservation.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "33333333-6666-0000-3333-111111111111",
3 | "type": "reservation-confirmed",
4 | "reservation": {
5 | "id": "33333333-6666-2222-1111-111111111111"
6 | },
7 | "context": {
8 | "order": {
9 | "id": "33333333-6666-1111-1111-111111111111",
10 | "sku": "1",
11 | "quanity": 1
12 | },
13 | "trigger": "33333333-6666-0000-2222-111111111111"
14 | }
15 | }
--------------------------------------------------------------------------------
/ch8/resubmitting-faults/cli/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-resubmitting-faults-cli",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "resubmit": "node index.js"
7 | },
8 | "dependencies": {
9 | "aws-sdk": "^2.45.0",
10 | "bluebird": "^3.5.0",
11 | "debug": "^2.6.4",
12 | "highland": "^2.11.1",
13 | "lodash": "^4.17.4",
14 | "moment": "^2.18.1",
15 | "yargs": "^7.1.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ch9/README.md:
--------------------------------------------------------------------------------
1 | # Optimizing Performance
2 |
3 | 1. [Tuning function-as-a-service](./tuning-faas)
4 | 2. [Batching requests](./frp-batching)
5 | 3. [Leveraging asynchronous non-blocking IO](./frp-async-non-blocking-io)
6 | 4. [Grouping events in stream processors](./frp-grouping)
7 | 5. [Autoscaling DynamoDB](./dynamodb-autoscaling)
8 | 6. [Utilizing cache-control](./cache-control)
9 | 7. [Leveraging session consistency](./session-consistency)
10 |
--------------------------------------------------------------------------------
/ch4/cdn-spa/README.md:
--------------------------------------------------------------------------------
1 | # Serving a single page app from the cdn
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch4/cdn-spa --path cncb-cdn-spa
5 | 2. cd cncb-cdn-spa
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run build
9 | 6. npm run dp:lcl -- -s $MY_STAGE
10 | 7. browse https://.cloudfront.net
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch8/idempotence-es/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-idempotence-es",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "dependencies": {
11 | "highland": "^2.11.1",
12 | "uuid": "^3.1.0"
13 | },
14 | "devDependencies": {
15 | "serverless": "1.26.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ch5/custom-authorizer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-custom-authorizer",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | },
13 | "dependencies": {
14 | "jsonwebtoken": "^8.2.1",
15 | "jwks-rsa": "^1.2.1"
16 | }
17 | }
--------------------------------------------------------------------------------
/ch2/event-first/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-event-first
2 |
3 | provider:
4 | name: aws
5 | runtime: nodejs8.10
6 | iamRoleStatements:
7 | - Effect: Allow
8 | Action:
9 | - kinesis:PutRecord
10 | Resource: ${cf:cncb-event-stream-${opt:stage}.streamArn}
11 |
12 | functions:
13 | submit:
14 | handler: handler.submit
15 | environment:
16 | STREAM_NAME: ${cf:cncb-event-stream-${opt:stage}.streamName}
17 |
18 |
--------------------------------------------------------------------------------
/ch3/saga/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-saga",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "highland": "^2.11.1",
16 | "uuid": "^3.1.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch4/cdn-invalidate/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-cdn-invalidate",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0"
12 | },
13 | "dependencies": {
14 | "highland": "^2.13.0",
15 | "uuid": "^3.2.1"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ch4/cdn-site/README.md:
--------------------------------------------------------------------------------
1 | # Serving a website from the cdn
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch4/cdn-site --path cncb-cdn-site
5 | 2. cd cncb-cdn-site
6 | 3. npm install
7 | 4. update serverless.yml with hosted zone id and domain name
8 | 5. npm test
9 | 7. npm run dp:lcl -- -s $MY_STAGE
10 | 8. browse see stack output
11 | 9. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch11/azure/README.md:
--------------------------------------------------------------------------------
1 | # Creating a service in Azure
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch11/azure --path cncb-azure
5 | 2. cd cncb-azure
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls logs -f hello -r 'East US' -s $MY_STAGE
10 | 7. curl -v https://cncb-azure-$MY_STAGE.azurewebsites.net/api/hello
11 | 8. npm run rm:lcl -- --stage $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/README.md:
--------------------------------------------------------------------------------
1 | # Writing contract tests for a asynchronous api
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch6/contract-testing-async --path cncb-contract-testing-async
5 | 2. cd cncb-contract-testing-async/upstream
6 | 3. npm install
7 | 4. npm test
8 | 5. DEBUG=replay REPLAY=record npm run test:int
9 | 6. repeat for cd cncb-contract-testing-async/downstream
10 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/fixtures/frontend/get:
--------------------------------------------------------------------------------
1 | GET /things/00000000-0000-0000-0000-000000000000
2 | accept-encoding: gzip, deflate
3 |
4 | HTTP/1.1 200 OK
5 | content-type: application/json; charset=utf-8
6 | access-control-allow-origin: *
7 | cache-control: max-age=3
8 | vary: origin,accept-encoding
9 | date: Sun, 17 Jun 2018 21:26:46 GMT
10 | connection: close
11 | transfer-encoding: chunked
12 |
13 | {"id":"00000000-0000-0000-0000-000000000000","name":"thing0"}
--------------------------------------------------------------------------------
/ch5/envelope-encryption/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-envelope-encryption",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "dependencies": {
11 | "crypto-js": "^3.1.9-1",
12 | "uuid": "^3.1.0"
13 | },
14 | "devDependencies": {
15 | "serverless": "1.26.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-contract-testing-sync-frontend",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test:int": "mocha --timeout 20000 ./test/int/**/*.test.js"
7 | },
8 | "devDependencies": {
9 | "aws-sdk": "^2.94.0",
10 | "aws-sdk-mock": "^1.7.0",
11 | "chai": "^4.1.2",
12 | "mocha": "^5.2.0",
13 | "replay": "^2.3.0",
14 | "supertest": "^3.1.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch4/cdn-spa/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-cdn-spa
2 |
3 | provider:
4 | name: aws
5 |
6 | plugins:
7 | - serverless-spa-deploy
8 | - serverless-spa-config
9 |
10 | custom:
11 | spa:
12 | files:
13 | - source: ./build
14 | globs: '**/*'
15 | headers:
16 | CacheControl: max-age=31536000 # 1 year
17 | - source: ./build
18 | globs: 'index.html'
19 | headers:
20 | CacheControl: max-age=300 # 5 minutes
21 |
--------------------------------------------------------------------------------
/ch5/account-as-code/README.md:
--------------------------------------------------------------------------------
1 | # Securing your cloud account
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch5/account-as-code --path cncb-account-as-code
5 | 2. cd cncb-account-as-code
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 |
10 | ## References
11 | * [IAM Best Practices](http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)
12 |
--------------------------------------------------------------------------------
/ch5/graphql-jwt/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-graphql-jwt
2 |
3 | provider:
4 | name: aws
5 | runtime: nodejs8.10
6 | # cfnRole: arn:aws:iam:::role/${opt:stage}-cfnRole
7 |
8 | functions:
9 | graphql:
10 | handler: handler.graphql
11 | events:
12 | - http:
13 | path: graphql
14 | method: post
15 | cors: true
16 | authorizer:
17 | arn: ${cf:cncb-cognito-pool-${opt:stage}.userPoolArn}
18 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/frontend/fixtures/0.0.0.0-3001/get:
--------------------------------------------------------------------------------
1 | GET /things/00000000-0000-0000-0000-000000000000
2 | accept-encoding: gzip, deflate
3 |
4 | HTTP/1.1 200 OK
5 | content-type: application/json; charset=utf-8
6 | access-control-allow-origin: *
7 | cache-control: max-age=3
8 | vary: origin,accept-encoding
9 | date: Sun, 17 Jun 2018 21:26:46 GMT
10 | connection: close
11 | transfer-encoding: chunked
12 |
13 | {"id":"00000000-0000-0000-0000-000000000000","name":"thing0"}
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-transitive-testing-author-frontend",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test:int": "mocha --timeout 20000 ./test/int/**/*.test.js"
7 | },
8 | "devDependencies": {
9 | "aws-sdk": "^2.94.0",
10 | "aws-sdk-mock": "^1.7.0",
11 | "chai": "^4.1.2",
12 | "mocha": "^5.2.0",
13 | "replay": "^2.3.0",
14 | "supertest": "^3.1.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch8/idempotence-inverse-oplock/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-idempotence-inverse-oplock",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "dependencies": {
11 | "highland": "^2.11.1",
12 | "uuid": "^3.1.0"
13 | },
14 | "devDependencies": {
15 | "serverless": "1.26.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-transitive-testing-customer-frontend",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test:int": "mocha --timeout 20000 ./test/int/**/*.test.js"
7 | },
8 | "devDependencies": {
9 | "aws-sdk": "^2.94.0",
10 | "aws-sdk-mock": "^1.7.0",
11 | "chai": "^4.1.2",
12 | "mocha": "^5.2.0",
13 | "replay": "^2.3.0",
14 | "supertest": "^3.1.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch10/regional-health-check/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-regional-health-check",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl:e": "sls deploy -v -r us-east-1",
8 | "dp:lcl:w": "sls deploy -v -r us-west-2",
9 | "rm:lcl:e": "sls remove -r us-east-1",
10 | "rm:lcl:w": "sls remove -r us-west-2"
11 | },
12 | "devDependencies": {
13 | "serverless": "1.26.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ch2/db-first-cognito/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-db-first-cognito",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "highland": "^2.11.1",
16 | "uuid": "^3.1.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch3/esg-inbound/README.md:
--------------------------------------------------------------------------------
1 | # Implementing an inbound external service gateway
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch3/esg-inbound --path cncb-esg-inbound
5 | 2. cd cncb-esg-inbound
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. https://developer.github.com/webhooks/creating
10 | 7. sls logs -f webhook -r us-east-1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch3/event-orchestration/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-event-orchestration",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "highland": "^2.11.1",
16 | "uuid": "^3.1.0"
17 | }
18 | }
--------------------------------------------------------------------------------
/ch4/README.md:
--------------------------------------------------------------------------------
1 | # Leveraging the Edge of the Cloud
2 |
3 | 1. [Serving a single page application from the CDN](./cdn-spa)
4 | 2. [Associating a custom domain name with a service](./cdn-dns)
5 | 3. [Serving a website from the CDN](./cdn-site)
6 | 4. [Deploying a service behind a CDN](./cdn-service)
7 | 5. [Serving static JSON from a CDN](./cdn-json)
8 | 6. [Trigging the invalidation of content in a CDN](./cdn-invalidate)
9 | 7. [Executing code at the edge of the cloud](./cdn-lambda)
10 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/fixtures/author-frontend/get-thing0:
--------------------------------------------------------------------------------
1 | GET /things/00000000-0000-0000-0000-000000000000
2 | accept-encoding: gzip, deflate
3 |
4 | HTTP/1.1 200 OK
5 | content-type: application/json; charset=utf-8
6 | access-control-allow-origin: *
7 | cache-control: max-age=3
8 | vary: origin,accept-encoding
9 | date: Sun, 17 Jun 2018 21:26:46 GMT
10 | connection: close
11 | transfer-encoding: chunked
12 |
13 | {"id":"00000000-0000-0000-0000-000000000000","name":"thing0"}
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-frontend/fixtures/0.0.0.0-3001/get-thing0:
--------------------------------------------------------------------------------
1 | GET /things/00000000-0000-0000-0000-000000000000
2 | accept-encoding: gzip, deflate
3 |
4 | HTTP/1.1 200 OK
5 | content-type: application/json; charset=utf-8
6 | access-control-allow-origin: *
7 | cache-control: max-age=3
8 | vary: origin,accept-encoding
9 | date: Sun, 17 Jun 2018 21:26:46 GMT
10 | connection: close
11 | transfer-encoding: chunked
12 |
13 | {"id":"00000000-0000-0000-0000-000000000000","name":"thing0"}
--------------------------------------------------------------------------------
/ch7/datadog-account/README.md:
--------------------------------------------------------------------------------
1 | # Monitoring a cloud-native system
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch7/datadog-account --path cncb-datadog-account
5 | 2. cd cncb-datadog-account
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 |
10 | ## References
11 | * [Datadog AWS Integration](https://docs.datadoghq.com/integrations/amazon_web_services/#setup)
12 |
--------------------------------------------------------------------------------
/ch7/event-metrics/README.md:
--------------------------------------------------------------------------------
1 | # Monitoring events
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch7/event-monitor --path cncb-event-monitor
5 | 2. cd cncb-event-monitor
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -f simulate -r us-east-1 -s $MY_STAGE
10 | 7. sls logs -f listener -r us-east-1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch1/create-api-gateway/handler.js:
--------------------------------------------------------------------------------
1 | module.exports.hello = (event, context, callback) => {
2 | console.log('event: %j', event);
3 |
4 | const response = {
5 | statusCode: 200,
6 | headers: {
7 | 'Access-Control-Allow-Origin': '*',
8 | },
9 | body: JSON.stringify({
10 | message: 'JavaScript Cloud Native Development Cookbook! Your function executed successfully!',
11 | input: event,
12 | }),
13 | };
14 |
15 | callback(null, response);
16 | };
17 |
--------------------------------------------------------------------------------
/ch1/create-function/README.md:
--------------------------------------------------------------------------------
1 | # Creating a function
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch1/create-function --path cncb-create-function
5 | 2. cd cncb-create-function
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -r us-east-1 -f hello -s $MY_STAGE -d '{"hello":"world"}'
10 | 7. sls logs -f hello -r us-east-1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
--------------------------------------------------------------------------------
/ch2/bi-directional-sync/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-bi-directional-sync",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "highland": "^2.11.1",
16 | "uuid": "^3.1.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch2/db-first-dynamodb/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-db-first-dynamodb",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "highland": "^2.11.1",
16 | "uuid": "^3.1.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch2/micro-event-store/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-micro-event-store",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "highland": "^2.11.1",
16 | "uuid": "^3.1.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch3/README.md:
--------------------------------------------------------------------------------
1 | # Implementing Autonomous Services
2 |
3 | 1. [Implementing a GraphQL CRUD BFF](./bff-graphql-crud)
4 | 2. [Implementing a search BFF](./bff-rest-search)
5 | 3. [Implementing an analytics BFF](./bff-rest-analytics)
6 | 4. [Implementing an inbound external service gateway](./esg-inbound)
7 | 5. [Implementing an outbound external service gateway](./esg-outbound)
8 | 6. [Orchestrating collaboration between services](./event-orchestration)
9 | 7. [Implementing a saga](./saga)
10 |
--------------------------------------------------------------------------------
/ch4/cdn-dns/README.md:
--------------------------------------------------------------------------------
1 | # Associating a custom domain name with a cdn
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch4/cdn-dns --path cncb-cdn-dns
5 | 2. cd cncb-cdn-dns
6 | 3. npm install
7 | 4. update serverless.yml with hosted zone id and domain name
8 | 5. npm test
9 | 6. npm run build
10 | 7. npm run dp:lcl -- -s $MY_STAGE
11 | 8. browse see stack output
12 | 9. npm run rm:lcl -- -s $MY_STAGE
13 |
--------------------------------------------------------------------------------
/ch6/README.md:
--------------------------------------------------------------------------------
1 | # Building a Continuous Deployment Pipeline
2 |
3 | 1. [Creating the CI/CD pipeline](./pipeline)
4 | 2. [Writing unit tests](./unit-testing)
5 | 3. [Writing integration tests](./integration-testing)
6 | 4. [Writing contract tests for a synchronous API](./contract-testing-sync)
7 | 5. [Writing contract tests for an asynchronous API](./contract-testing-async)
8 | 6. [Assembling transitive end-to-end tests](./transitive-testing)
9 | 7. [Leveraging feature flags](./feature-flag)
10 |
--------------------------------------------------------------------------------
/ch8/handling-faults/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-handling-faults",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -v -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -v -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "highland": "^2.13.0",
16 | "uuid": "^3.2.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch9/cache-control/README.md:
--------------------------------------------------------------------------------
1 | # Utilizing cache-control
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch9/cache-control --path cncb-cache-control
5 | 2. cd cncb-cache-control
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. curl -s -w "%{time_total}\n" -o /dev/null https://xyz.cloudfront.net/get
10 | 7. sls logs -f get -r us-east-1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch10/regional-failover/check/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-regional-failover-check",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl:e": "sls deploy -v -r us-east-1",
8 | "dp:lcl:w": "sls deploy -v -r us-west-2",
9 | "rm:lcl:e": "sls remove -v -r us-east-1",
10 | "rm:lcl:w": "sls remove -v -r us-west-2"
11 | },
12 | "devDependencies": {
13 | "serverless": "1.26.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ch2/materialized-view-s3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-materialized-view-s3",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "highland": "^2.11.1",
16 | "uuid": "^3.1.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch3/bff-rest-analytics/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-bff-rest-analytics",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "highland": "^2.11.1",
16 | "moment": "^2.22.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch4/cdn-service/README.md:
--------------------------------------------------------------------------------
1 | # Deploying a service behind a cdn
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch4/cdn-service --path cncb-cdn-service
5 | 2. cd cncb-cdn-service
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. curl -s -w "%{time_total}\n" -o /dev/null https://xyz.cloudfront.net/hello
10 | 7. sls logs -f hello -r us-east-1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch5/cognito-authorizer/handler.js:
--------------------------------------------------------------------------------
1 | module.exports.hello = (request, context, callback) => {
2 | console.log('request: %j', request);
3 |
4 | const response = {
5 | statusCode: 200,
6 | headers: {
7 | 'Access-Control-Allow-Origin': '*',
8 | },
9 | body: JSON.stringify({
10 | message: 'JavaScript Cloud Native Development Cookbook! Your function executed successfully!',
11 | input: request,
12 | }),
13 | };
14 |
15 | callback(null, response);
16 | };
17 |
--------------------------------------------------------------------------------
/ch4/cdn-site/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-cdn-site
2 |
3 | provider:
4 | name: aws
5 |
6 | plugins:
7 | - serverless-spa-deploy
8 | - serverless-spa-config
9 |
10 | custom:
11 | spa:
12 | files:
13 | - source: ./dist
14 | globs: '**/*'
15 | headers:
16 | CacheControl: max-age=31536000 # 1 year
17 | redirect: true
18 | dns:
19 | hostedZoneId: Z1234567890123
20 | domainName: example.com
21 | endpoint: www.${self:custom.dns.domainName}
22 |
--------------------------------------------------------------------------------
/ch9/frp-batching/README.md:
--------------------------------------------------------------------------------
1 | # Batching requests
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch9/frp-batching --path cncb-frp-batching
5 | 2. cd cncb-frp-batching
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -f simulate -r us-east-1 -s $MY_STAGE
10 | 7. sls logs -f listener -r us-east-1 -s $MY_STAGE --filter 'event count'
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch1/deploy-spa/README.md:
--------------------------------------------------------------------------------
1 | # Deploying a single page application
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch1/deploy-spa --path cncb-deploy-spa
5 | 2. cd cncb-deploy-spa
6 | 3. npm install
7 | 4. npm start
8 | 5. npm test
9 | 6. npm run build
10 | 7. npm run dp:lcl -- -s $MY_STAGE
11 | 8. browse http://cncb-deploy-spa-$MY_STAGE-websitebucket-xxxx.s3-website-us-east-1.amazonaws.com
12 | 9. npm run rm:lcl -- -s $MY_STAGE
13 |
--------------------------------------------------------------------------------
/ch2/materialized-view-cognito/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-materialized-view-cognito",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "highland": "^2.11.1",
16 | "uuid": "^3.1.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch2/materialized-view-dynamodb/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-materialized-view-dynamodb",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "highland": "^2.11.1",
16 | "uuid": "^3.1.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch4/cdn-invalidate/includes.yml:
--------------------------------------------------------------------------------
1 | BucketTopicPolicy:
2 | Type: AWS::SNS::TopicPolicy
3 | Properties:
4 | Topics:
5 | - Ref: BucketTopic
6 | PolicyDocument:
7 | Statement:
8 | - Effect: Allow
9 | Principal:
10 | Service: s3.amazonaws.com
11 | Action: sns:Publish
12 | Resource:
13 | Ref: BucketTopic
14 | Condition:
15 | ArnLike:
16 | aws:SourceArn: arn:aws:s3:::${self:service}-${opt:stage}-bucket-*
--------------------------------------------------------------------------------
/ch5/cognito-authorizer/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-cognito-authorizer
2 |
3 | provider:
4 | name: aws
5 | # cfnRole: arn:aws:iam:::role/${opt:stage}-cfnRole
6 | runtime: nodejs8.10
7 | endpointType: REGIONAL
8 |
9 | functions:
10 | hello:
11 | handler: handler.hello
12 | events:
13 | - http:
14 | path: hello
15 | method: get
16 | cors: true
17 | authorizer:
18 | arn: ${cf:cncb-cognito-pool-${opt:stage}.userPoolArn}
19 |
--------------------------------------------------------------------------------
/ch5/dr/src1-account/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-dr-src1-account",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "serverless": "1.26.0",
12 | "serverless-pseudo-parameters": "^1.6.0"
13 | },
14 | "dependencies": {
15 | "moment": "^2.22.2",
16 | "uuid": "^3.2.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-bff/fixtures/customer-frontend/get-thing0:
--------------------------------------------------------------------------------
1 | GET /things/00000000-0000-0000-0000-000000000000
2 | accept-encoding: gzip, deflate
3 |
4 | HTTP/1.1 200 OK
5 | content-type: application/json; charset=utf-8
6 | access-control-allow-origin: *
7 | cache-control: max-age=3
8 | vary: origin,accept-encoding
9 | date: Tue, 26 Jun 2018 02:21:25 GMT
10 | connection: close
11 | transfer-encoding: chunked
12 |
13 | {"id":"00000000-0000-0000-0000-000000000000","name":"thing0","asOf":1529179380000}
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-frontend/fixtures/0.0.0.0-3001/get-thing0:
--------------------------------------------------------------------------------
1 | GET /things/00000000-0000-0000-0000-000000000000
2 | accept-encoding: gzip, deflate
3 |
4 | HTTP/1.1 200 OK
5 | content-type: application/json; charset=utf-8
6 | access-control-allow-origin: *
7 | cache-control: max-age=3
8 | vary: origin,accept-encoding
9 | date: Tue, 26 Jun 2018 02:21:25 GMT
10 | connection: close
11 | transfer-encoding: chunked
12 |
13 | {"id":"00000000-0000-0000-0000-000000000000","name":"thing0","asOf":1529179380000}
--------------------------------------------------------------------------------
/ch7/custom-metrics/README.md:
--------------------------------------------------------------------------------
1 | # Implementing custom metrics
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch7/custom-metrics --path cncb-custom-metrics
5 | 2. cd cncb-custom-metrics
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. curl -v https://xyz.execute-api.us-east-1.amazonaws.com/$MY_STAGE/hello | json_pp
10 | 7. sls logs -f hello -r us-east-1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch8/resubmitting-faults/simulator/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-resubmitting-faults-simulator",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "highland": "^2.11.1",
16 | "uuid": "^3.1.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch3/bff-rest-search/includes.yml:
--------------------------------------------------------------------------------
1 | BucketTopicPolicy:
2 | Type: AWS::SNS::TopicPolicy
3 | Properties:
4 | Topics:
5 | - Ref: BucketTopic
6 | PolicyDocument:
7 | Statement:
8 | - Effect: Allow
9 | Principal:
10 | Service: s3.amazonaws.com
11 | Action: sns:Publish
12 | Resource:
13 | Ref: BucketTopic
14 | Condition:
15 | ArnLike:
16 | aws:SourceArn: arn:aws:s3:::${self:service}-${opt:stage}-bucket-*
--------------------------------------------------------------------------------
/ch3/esg-outbound/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-esg-outbound",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "highland": "^2.11.1",
16 | "isomorphic-fetch": "^2.2.1",
17 | "uuid": "^3.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ch7/custom-metrics/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-custom-metrics
2 |
3 | provider:
4 | name: aws
5 | runtime: nodejs8.10
6 |
7 | functions:
8 | hello:
9 | handler: handler.hello
10 | events:
11 | - http:
12 | path: hello
13 | method: get
14 | cors: true
15 | environment:
16 | ACCOUNT_NAME: ${opt:account}
17 | SERVERLESS_STAGE: ${opt:stage}
18 | SERVERLESS_PROJECT: ${self:service}
19 | MONITOR_ADVANCED: false
20 | DEBUG: '*'
21 |
--------------------------------------------------------------------------------
/ch8/handling-faults/README.md:
--------------------------------------------------------------------------------
1 | # Handling Faults
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch8/handling-faults --path cncb-handling-faults
5 | 2. cd cncb-handling-faults
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -f simulate -r us-east-1 -s $MY_STAGE
10 | 7. sls logs -f listener -r us-east-1 -s $MY_STAGE --filter 'publishing fault'
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch8/idempotence-es/README.md:
--------------------------------------------------------------------------------
1 | # Implementing idempotency with event sourcing
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch8/idempotence-es --path cncb-idempotence-es
5 | 2. cd cncb-idempotence-es
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -f simulate -r us-east-1 -s $MY_STAGE
10 | 7. sls logs -f trigger -r us-east-1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch8/resubmitting-faults/monitor/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-resubmitting-faults-monitor",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -v -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "highland": "^2.11.1",
16 | "moment": "^2.22.2"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch10/round-robin-replication/includes.yml:
--------------------------------------------------------------------------------
1 | BucketTopicPolicy:
2 | Type: AWS::SNS::TopicPolicy
3 | Properties:
4 | Topics:
5 | - Ref: BucketTopic
6 | PolicyDocument:
7 | Statement:
8 | - Effect: Allow
9 | Principal:
10 | Service: s3.amazonaws.com
11 | Action: sns:Publish
12 | Resource:
13 | Ref: BucketTopic
14 | Condition:
15 | ArnLike:
16 | aws:SourceArn: arn:aws:s3:::${self:service}-${opt:stage}-bucket-*
--------------------------------------------------------------------------------
/ch5/cognito-pool/README.md:
--------------------------------------------------------------------------------
1 | # Creating a federated identity pool
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch5/cognito-pool --path cncb-cognito-pool
5 | 2. cd cncb-cognito-pool
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. https://cncb-$MY_STAGE.auth.us-east-1.amazoncognito.com/login?redirect_uri=http://localhost:3000/signin&response_type=token&client_id=
10 | 7. npm run rm:lcl -- -s $MY_STAGE
11 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/fixtures/frontend/save:
--------------------------------------------------------------------------------
1 | POST /things
2 | accept-encoding: gzip, deflate
3 | content-type: application/json
4 | body: {\"name\":\"thing0\"}
5 |
6 | HTTP/1.1 201 Created
7 | content-type: application/json; charset=utf-8
8 | access-control-allow-origin: *
9 | cache-control: no-cache
10 | location: https://0.0.0.0:3001/stg/things/00000000-0000-0000-0000-000000000000
11 | vary: origin,accept-encoding
12 | content-length: 0
13 | date: Sun, 17 Jun 2018 21:26:46 GMT
14 | connection: close
15 |
16 |
--------------------------------------------------------------------------------
/ch9/frp-grouping/README.md:
--------------------------------------------------------------------------------
1 | # Grouping events in stream processors
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch9/frp-grouping --path cncb-frp-grouping
5 | 2. cd cncb-frp-grouping
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -f simulate -r us-east-1 -s $MY_STAGE
10 | 7. sls logs -f listener -r us-east-1 -s $MY_STAGE --filter 'event count'
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch1/create-api-gateway/README.md:
--------------------------------------------------------------------------------
1 | # Creating an api gateway
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch1/create-api-gateway --path cncb-create-api-gateway
5 | 2. cd cncb-create-api-gateway
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. curl -v https://xyz.execute-api.us-east-1.amazonaws.com/$MY_STAGE/hello | json_pp
10 | 7. sls logs -f hello -r us-east-1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch4/cdn-dns/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-title {
18 | font-size: 1.5em;
19 | }
20 |
21 | .App-intro {
22 | font-size: large;
23 | }
24 |
25 | @keyframes App-logo-spin {
26 | from { transform: rotate(0deg); }
27 | to { transform: rotate(360deg); }
28 | }
29 |
--------------------------------------------------------------------------------
/ch4/cdn-spa/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-title {
18 | font-size: 1.5em;
19 | }
20 |
21 | .App-intro {
22 | font-size: large;
23 | }
24 |
25 | @keyframes App-logo-spin {
26 | from { transform: rotate(0deg); }
27 | to { transform: rotate(360deg); }
28 | }
29 |
--------------------------------------------------------------------------------
/ch8/timeout-retry/README.md:
--------------------------------------------------------------------------------
1 | # Employing proper timeouts and retries
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch8/timeout-retry --path cncb-timeout-retry
5 | 2. cd cncb-timeout-retry
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -f command -r us-east-1 -s $MY_STAGE -d '{"name":"thing one"}'
10 | 7. sls logs -f command -r us-east-1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch1/deploy-spa/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-title {
18 | font-size: 1.5em;
19 | }
20 |
21 | .App-intro {
22 | font-size: large;
23 | }
24 |
25 | @keyframes App-logo-spin {
26 | from { transform: rotate(0deg); }
27 | to { transform: rotate(360deg); }
28 | }
29 |
--------------------------------------------------------------------------------
/ch4/cdn-service/handler.js:
--------------------------------------------------------------------------------
1 | module.exports.hello = (request, context, callback) => {
2 | console.log('request: %j', request);
3 |
4 | const response = {
5 | statusCode: 200,
6 | headers: {
7 | 'Access-Control-Allow-Origin': '*',
8 | 'Cache-Control': 'max-age=5',
9 | },
10 | body: JSON.stringify({
11 | message: 'JavaScript Cloud Native Development Cookbook! Your function executed successfully!',
12 | input: request,
13 | }),
14 | };
15 |
16 | callback(null, response);
17 | };
18 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/frontend/fixtures/0.0.0.0-3001/save:
--------------------------------------------------------------------------------
1 | POST /things
2 | accept-encoding: gzip, deflate
3 | content-type: application/json
4 | body: {\"name\":\"thing0\"}
5 |
6 | HTTP/1.1 201 Created
7 | content-type: application/json; charset=utf-8
8 | access-control-allow-origin: *
9 | cache-control: no-cache
10 | location: https://0.0.0.0:3001/stg/things/00000000-0000-0000-0000-000000000000
11 | vary: origin,accept-encoding
12 | content-length: 0
13 | date: Sun, 17 Jun 2018 21:26:46 GMT
14 | connection: close
15 |
16 |
--------------------------------------------------------------------------------
/ch6/feature-flag/src/Home.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-title {
18 | font-size: 1.5em;
19 | }
20 |
21 | .App-intro {
22 | font-size: large;
23 | }
24 |
25 | @keyframes App-logo-spin {
26 | from { transform: rotate(0deg); }
27 | to { transform: rotate(360deg); }
28 | }
29 |
--------------------------------------------------------------------------------
/ch7/synthetics/src/Home.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-title {
18 | font-size: 1.5em;
19 | }
20 |
21 | .App-intro {
22 | font-size: large;
23 | }
24 |
25 | @keyframes App-logo-spin {
26 | from { transform: rotate(0deg); }
27 | to { transform: rotate(360deg); }
28 | }
29 |
--------------------------------------------------------------------------------
/ch1/event-stream/README.md:
--------------------------------------------------------------------------------
1 | # Creating an event stream and publishing an event
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch1/event-stream --path cncb-event-stream
5 | 2. cd cncb-event-stream
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -r us-east-1 -f publish -s $MY_STAGE -d '{"type":"thing-created"}'
10 | 7. sls logs -f publish -r us-east-1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ch3/esg-outbound/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-esg-outbound
2 |
3 | provider:
4 | name: aws
5 | runtime: nodejs8.10
6 | environment:
7 | REPO: enter-your-github-project
8 | OWNER: enter-your-github-id
9 | TOKEN: enter-your-github-token
10 |
11 | functions:
12 | listener:
13 | handler: handler.listener
14 | events:
15 | - stream:
16 | type: kinesis
17 | arn: ${cf:cncb-event-stream-${opt:stage}.streamArn}
18 | batchSize: 100
19 | startingPosition: TRIM_HORIZON
20 |
--------------------------------------------------------------------------------
/ch5/cognito-signin/README.md:
--------------------------------------------------------------------------------
1 | # Implementing sign up, sign in and sign out
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch5/cognito-signin --path cncb-cognito-signin
5 | 2. cd cncb-cognito-signin
6 | 3. npm install
7 | 4. Update src/App.js
8 | 4. npm start
9 | 6. npm run build
10 | 7. Browse to http://localhost:3000
11 | 8. Click Sign Up and complete form
12 | 9. Click Sign Out
13 | 10. Click Sign In again
14 | 11. Review the idToken displayed on the page
15 |
--------------------------------------------------------------------------------
/ch5/cognito-signin/src/Home.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-title {
18 | font-size: 1.5em;
19 | }
20 |
21 | .App-intro {
22 | font-size: large;
23 | }
24 |
25 | @keyframes App-logo-spin {
26 | from { transform: rotate(0deg); }
27 | to { transform: rotate(360deg); }
28 | }
29 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/fixtures/author-frontend/save-thing0:
--------------------------------------------------------------------------------
1 | POST /things
2 | accept-encoding: gzip, deflate
3 | content-type: application/json
4 | body: {\"name\":\"thing0\"}
5 |
6 | HTTP/1.1 201 Created
7 | content-type: application/json; charset=utf-8
8 | access-control-allow-origin: *
9 | cache-control: no-cache
10 | location: https://0.0.0.0:3001/stg/things/00000000-0000-0000-0000-000000000000
11 | vary: origin,accept-encoding
12 | content-length: 0
13 | date: Sun, 17 Jun 2018 21:26:46 GMT
14 | connection: close
15 |
16 |
--------------------------------------------------------------------------------
/ch9/dynamodb-autoscaling/README.md:
--------------------------------------------------------------------------------
1 | # Autoscaling DynamoDB
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch9/dynamodb-autoscaling --path cncb-dynamodb-autoscaling
5 | 2. cd cncb-dynamodb-autoscaling
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -f simulate -r us-east-1 -s $MY_STAGE
10 | 7. sls logs -f listener -r us-east-1 -s $MY_STAGE --filter 'event count'
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch9/tuning-faas/src/connector/stream.js:
--------------------------------------------------------------------------------
1 | import { Kinesis } from 'aws-sdk';
2 |
3 | class Connector {
4 | constructor(streamName) {
5 | this.streamName = streamName;
6 | this.stream = new Kinesis();
7 | }
8 |
9 | publish(event) {
10 | const params = {
11 | StreamName: this.streamName,
12 | PartitionKey: event.partitionKey,
13 | Data: Buffer.from(JSON.stringify(event)),
14 | };
15 |
16 | return this.stream.putRecord(params).promise();
17 | }
18 | }
19 |
20 | export default Connector;
21 |
--------------------------------------------------------------------------------
/ch3/esg-inbound/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-esg-inbound
2 |
3 | provider:
4 | name: aws
5 | runtime: nodejs8.10
6 | iamRoleStatements:
7 | - Effect: Allow
8 | Action:
9 | - kinesis:PutRecord
10 | Resource: ${cf:cncb-event-stream-${opt:stage}.streamArn}
11 |
12 | functions:
13 | webhook:
14 | handler: handler.webhook
15 | events:
16 | - http:
17 | path: webhook
18 | method: post
19 | environment:
20 | STREAM_NAME: ${cf:cncb-event-stream-${opt:stage}.streamName}
21 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-frontend/fixtures/0.0.0.0-3001/save-thing0:
--------------------------------------------------------------------------------
1 | POST /things
2 | accept-encoding: gzip, deflate
3 | content-type: application/json
4 | body: {\"name\":\"thing0\"}
5 |
6 | HTTP/1.1 201 Created
7 | content-type: application/json; charset=utf-8
8 | access-control-allow-origin: *
9 | cache-control: no-cache
10 | location: https://0.0.0.0:3001/stg/things/00000000-0000-0000-0000-000000000000
11 | vary: origin,accept-encoding
12 | content-length: 0
13 | date: Sun, 17 Jun 2018 21:26:46 GMT
14 | connection: close
15 |
16 |
--------------------------------------------------------------------------------
/ch9/session-consistency/spa/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-title {
18 | font-size: 1.5em;
19 | }
20 |
21 | .App-intro {
22 | font-size: large;
23 | }
24 |
25 | @keyframes App-logo-spin {
26 | from { transform: rotate(0deg); }
27 | to { transform: rotate(360deg); }
28 | }
29 |
--------------------------------------------------------------------------------
/ch10/latency-based-routing/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-latency-based-routing",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl:e": "sls deploy -v -r us-east-1",
8 | "dp:lcl:w": "sls deploy -v -r us-west-2",
9 | "rm:lcl:e": "sls remove -v -r us-east-1",
10 | "rm:lcl:w": "sls remove -v -r us-west-2"
11 | },
12 | "devDependencies": {
13 | "serverless": "1.26.0",
14 | "serverless-multi-regional-plugin": "^1.0.1"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch9/frp-batching/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-frp-batching",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -v -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -v -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "bluebird": "^3.5.1",
16 | "highland": "^2.13.0",
17 | "moment": "^2.22.1",
18 | "uuid": "^3.2.1"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ch9/frp-grouping/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-frp-grouping",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -v -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -v -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "bluebird": "^3.5.1",
16 | "highland": "^2.13.0",
17 | "moment": "^2.22.1",
18 | "uuid": "^3.2.1"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ch10/latency-based-routing/handler.js:
--------------------------------------------------------------------------------
1 | module.exports.hello = (request, context, callback) => {
2 | console.log('Request: %j', request);
3 | console.log('Context: %j', context);
4 | console.log('Env: %j', process.env);
5 |
6 | const response = {
7 | statusCode: 200,
8 | body: JSON.stringify({
9 | timestamp: Date.now(),
10 | message: `Your function executed successfully in ${process.env.AWS_REGION}!`,
11 | }),
12 | };
13 |
14 | console.log('Response: %j', response);
15 |
16 | callback(null, response);
17 | };
18 |
--------------------------------------------------------------------------------
/ch10/regional-failover/service/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-regional-failover-service",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test",
7 | "dp:lcl:e": "sls deploy -v -r us-east-1",
8 | "dp:lcl:w": "sls deploy -v -r us-west-2",
9 | "rm:lcl:e": "sls remove -v -r us-east-1",
10 | "rm:lcl:w": "sls remove -v -r us-west-2"
11 | },
12 | "devDependencies": {
13 | "serverless": "1.26.0",
14 | "serverless-multi-regional-plugin": "^1.0.1"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch2/db-first-cognito/README.md:
--------------------------------------------------------------------------------
1 | # Applying the database-first variant of the event sourcing pattern with Cognito Datasets
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch2/db-first-cognito --path cncb-db-first-cognito
5 | 2. cd cncb-db-first-dynamodb
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. update, open and execute index.html
10 | 7. sls logs -f trigger -r us-east-1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch2/replaying-events/README.md:
--------------------------------------------------------------------------------
1 | # Replaying events
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch2/replaying-events --path cncb-replaying-events
5 | 2. cd cncb-replaying-events
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. node index.js replay --bucket --prefix --function --dry false
10 | 7. sls logs -f listener -r us-east-1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch10/regional-failover/service/handler.js:
--------------------------------------------------------------------------------
1 | module.exports.hello = (request, context, callback) => {
2 | console.log('Request: %j', request);
3 | console.log('Context: %j', context);
4 | console.log('Env: %j', process.env);
5 |
6 | const response = {
7 | statusCode: 200,
8 | body: JSON.stringify({
9 | timestamp: Date.now(),
10 | message: `Your function executed successfully in ${process.env.AWS_REGION}!`,
11 | }),
12 | };
13 |
14 | console.log('Response: %j', response);
15 |
16 | callback(null, response);
17 | };
18 |
--------------------------------------------------------------------------------
/ch5/graphql-jwt/lib/fixtures.js:
--------------------------------------------------------------------------------
1 | const thingsData = [
2 | {
3 | id: '55555555-6666-1111-0000-000000000000',
4 | name: 'thing0',
5 | description: 'Thing none of two.',
6 | },
7 | {
8 | id: '55555555-6666-1111-1111-000000000000',
9 | name: 'thing1',
10 | description: 'Thing one of two.',
11 | },
12 | {
13 | id: '55555555-6666-1111-2222-000000000000',
14 | name: 'thing2',
15 | description: 'Thing two of two.',
16 | },
17 | ];
18 |
19 | module.exports = thingsData;
--------------------------------------------------------------------------------
/ch7/custom-metrics/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-custom-metrics",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1 -s test --account cncb",
7 | "dp:lcl": "sls deploy -v -r us-east-1 --account cncb",
8 | "rm:lcl": "sls remove -r us-east-1 --account cncb"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "debug": "^3.1.0",
16 | "serverless-datadog-metrics": "^1.0.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ch7/synthetics/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-synthetics
2 |
3 | provider:
4 | name: aws
5 | # cfnRole: arn:aws:iam:::role/${opt:stage}-cfnRole
6 |
7 | plugins:
8 | - serverless-spa-deploy
9 | - serverless-spa-config
10 |
11 | custom:
12 | spa:
13 | files:
14 | - source: ./build
15 | globs: '**/*'
16 | headers:
17 | CacheControl: max-age=31536000 # 1 year
18 | - source: ./build
19 | globs: 'index.html'
20 | headers:
21 | CacheControl: max-age=300 # 5 minutes
22 |
--------------------------------------------------------------------------------
/ch5/graphql-jwt/schema/thing/resolvers.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | Query: {
3 | thing(_, { id }, ctx) {
4 | return ctx.models.Thing.getById(id);
5 | },
6 | things(_, { name, limit, cursor }, ctx) {
7 | return ctx.models.Thing.queryByName(name, limit, cursor);
8 | },
9 | },
10 | Mutation: {
11 | saveThing: (_, { input }, ctx) => {
12 | return ctx.models.Thing.save(input.id, input);
13 | },
14 | deleteThing: (_, args, ctx) => {
15 | return ctx.models.Thing.delete(args.id);
16 | },
17 | },
18 | };
19 |
--------------------------------------------------------------------------------
/ch6/unit-testing/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | trim_trailing_whitespace = true
9 | end_of_line = lf
10 | insert_final_newline = true
11 |
12 | # Set default charset
13 | [*.{js,ts,css,json}]
14 | charset = utf-8
15 | indent_style = space
16 | indent_size = 2
17 |
18 | # Matches the exact files package.json
19 | [{package.json}]
20 | indent_style = space
21 | indent_size = 2
22 |
--------------------------------------------------------------------------------
/ch3/bff-graphql-crud/schema/thing/resolvers.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | Query: {
3 | thing(_, { id }, ctx) {
4 | return ctx.models.Thing.getById(id);
5 | },
6 | things(_, { name, limit, cursor }, ctx) {
7 | return ctx.models.Thing.queryByName(name, limit, cursor);
8 | },
9 | },
10 | Mutation: {
11 | saveThing: (_, { input }, ctx) => {
12 | return ctx.models.Thing.save(input.id, input);
13 | },
14 | deleteThing: (_, args, ctx) => {
15 | return ctx.models.Thing.delete(args.id);
16 | },
17 | },
18 | };
19 |
--------------------------------------------------------------------------------
/ch4/cdn-site/content/posts/first-post.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "First post"
3 | date: "2017-01-01"
4 | ---
5 |
6 | # This is a [Markdown](https://en.wikipedia.org/wiki/Markdown#Example) file
7 |
8 | If you are new to Markdown, you might want to check those links:
9 |
10 | * [What is Markdown?](http://whatismarkdown.com/)
11 | * [Mastering Markdown, a GitHub guide](https://guides.github.com/features/mastering-markdown/)
12 | * [wikipedia.org/wiki/Markdown](https://en.wikipedia.org/wiki/Markdown#Example)
13 | * [masteringmarkdown.com](http://masteringmarkdown.com/)
14 |
--------------------------------------------------------------------------------
/ch6/pipeline/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-pipeline",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "echo running unit tests...",
7 | "test:int": "echo running integration tests...",
8 | "dp:lcl": "sls deploy -v -r us-east-1 --acct dev",
9 | "rm:lcl": "sls remove -r us-east-1 --acct dev",
10 | "dp:stg:e": "sls deploy -v -r us-east-1 -s stg --acct dev",
11 | "dp:prd:e": "sls deploy -v -r us-east-1 -s prd --acct prod"
12 | },
13 | "devDependencies": {
14 | "serverless": "1.26.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch8/backpressure-ratelimit/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-backpressure-ratelimit",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -v -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -v -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "bluebird": "^3.5.1",
16 | "highland": "^2.13.0",
17 | "moment": "^2.22.1",
18 | "uuid": "^3.2.1"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ch8/idempotence-inverse-oplock/README.md:
--------------------------------------------------------------------------------
1 | # Implementing idempotency with an inverse oplock
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch8/idempotence-inverse-oplock --path cncb-idempotence-inverse-oplock
5 | 2. cd cncb-idempotence-inverse-oplock
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -f simulate -r us-east-1 -s $MY_STAGE
10 | 7. sls logs -f listener -r us-east-1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch6/integration-testing/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | trim_trailing_whitespace = true
9 | end_of_line = lf
10 | insert_final_newline = true
11 |
12 | # Set default charset
13 | [*.{js,ts,css,json}]
14 | charset = utf-8
15 | indent_style = space
16 | indent_size = 2
17 |
18 | # Matches the exact files package.json
19 | [{package.json}]
20 | indent_style = space
21 | indent_size = 2
22 |
--------------------------------------------------------------------------------
/ch6/unit-testing/.nycrc:
--------------------------------------------------------------------------------
1 | {
2 | "lines": 100,
3 | "statements": 100,
4 | "functions": 100,
5 | "branches": 100,
6 | "include": [
7 | "src/**/*.js"
8 | ],
9 | "exclude": [
10 | "test/int/**/*.test.js",
11 | "test/unit/**/*.test.js"
12 | ],
13 | "require": [],
14 | "reporter": [
15 | "text",
16 | "lcov",
17 | "html",
18 | "text-summary"
19 | ],
20 | "sourceMap": false,
21 | "instrument": false,
22 | "cache": false,
23 | "check-coverage": true,
24 | "all": true
25 | }
26 |
--------------------------------------------------------------------------------
/ch8/backpressure-ratelimit/README.md:
--------------------------------------------------------------------------------
1 | # Implementing backpressure and rate limiting
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch8/backpressure-ratelimit --path cncb-backpressure-ratelimit
5 | 2. cd cncb-backpressure-ratelimit
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -f simulate -r us-east-1 -s $MY_STAGE
10 | 7. sls logs -f listener -r us-east-1 -s $MY_STAGE --filter 'event count'
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch9/frp-async-non-blocking-io/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-frp-async-non-blocking-io",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -v -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -v -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "bluebird": "^3.5.1",
16 | "highland": "^2.13.0",
17 | "moment": "^2.22.1",
18 | "uuid": "^3.2.1"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | trim_trailing_whitespace = true
9 | end_of_line = lf
10 | insert_final_newline = true
11 |
12 | # Set default charset
13 | [*.{js,ts,css,json}]
14 | charset = utf-8
15 | indent_style = space
16 | indent_size = 2
17 |
18 | # Matches the exact files package.json
19 | [{package.json}]
20 | indent_style = space
21 | indent_size = 2
22 |
--------------------------------------------------------------------------------
/ch9/frp-async-non-blocking-io/README.md:
--------------------------------------------------------------------------------
1 | # Leveraging asynchronous non-blocking IO
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch9/frp-async-non-blocking-io --path cncb-frp-async-non-blocking-io
5 | 2. cd cncb-frp-async-non-blocking-io
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -f simulate -r us-east-1 -s $MY_STAGE
10 | 7. sls logs -f listener -r us-east-1 -s $MY_STAGE --filter 'event count'
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
--------------------------------------------------------------------------------
/ch9/session-consistency/service/schema/thing/resolvers.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | Query: {
3 | thing(_, { id }, ctx) {
4 | return ctx.models.Thing.getById(id);
5 | },
6 | things(_, { name, limit, cursor }, ctx) {
7 | return ctx.models.Thing.queryByName(name, limit, cursor);
8 | },
9 | },
10 | Mutation: {
11 | saveThing: (_, { input }, ctx) => {
12 | return ctx.models.Thing.save(input.id, input);
13 | },
14 | deleteThing: (_, args, ctx) => {
15 | return ctx.models.Thing.delete(args.id);
16 | },
17 | },
18 | };
19 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/upstream/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | trim_trailing_whitespace = true
9 | end_of_line = lf
10 | insert_final_newline = true
11 |
12 | # Set default charset
13 | [*.{js,ts,css,json}]
14 | charset = utf-8
15 | indent_style = space
16 | indent_size = 2
17 |
18 | # Matches the exact files package.json
19 | [{package.json}]
20 | indent_style = space
21 | indent_size = 2
22 |
--------------------------------------------------------------------------------
/ch6/integration-testing/.nycrc:
--------------------------------------------------------------------------------
1 | {
2 | "lines": 100,
3 | "statements": 100,
4 | "functions": 100,
5 | "branches": 100,
6 | "include": [
7 | "src/**/*.js"
8 | ],
9 | "exclude": [
10 | "test/int/**/*.test.js",
11 | "test/unit/**/*.test.js"
12 | ],
13 | "require": [],
14 | "reporter": [
15 | "text",
16 | "lcov",
17 | "html",
18 | "text-summary"
19 | ],
20 | "sourceMap": false,
21 | "instrument": false,
22 | "cache": false,
23 | "check-coverage": true,
24 | "all": true
25 | }
26 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | trim_trailing_whitespace = true
9 | end_of_line = lf
10 | insert_final_newline = true
11 |
12 | # Set default charset
13 | [*.{js,ts,css,json}]
14 | charset = utf-8
15 | indent_style = space
16 | indent_size = 2
17 |
18 | # Matches the exact files package.json
19 | [{package.json}]
20 | indent_style = space
21 | indent_size = 2
22 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-bff/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | trim_trailing_whitespace = true
9 | end_of_line = lf
10 | insert_final_newline = true
11 |
12 | # Set default charset
13 | [*.{js,ts,css,json}]
14 | charset = utf-8
15 | indent_style = space
16 | indent_size = 2
17 |
18 | # Matches the exact files package.json
19 | [{package.json}]
20 | indent_style = space
21 | indent_size = 2
22 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/downstream/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | trim_trailing_whitespace = true
9 | end_of_line = lf
10 | insert_final_newline = true
11 |
12 | # Set default charset
13 | [*.{js,ts,css,json}]
14 | charset = utf-8
15 | indent_style = space
16 | indent_size = 2
17 |
18 | # Matches the exact files package.json
19 | [{package.json}]
20 | indent_style = space
21 | indent_size = 2
22 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/.nycrc:
--------------------------------------------------------------------------------
1 | {
2 | "lines": 100,
3 | "statements": 100,
4 | "functions": 100,
5 | "branches": 100,
6 | "include": [
7 | "src/**/*.js"
8 | ],
9 | "exclude": [
10 | "test/int/**/*.test.js",
11 | "test/unit/**/*.test.js"
12 | ],
13 | "require": [],
14 | "reporter": [
15 | "text",
16 | "lcov",
17 | "html",
18 | "text-summary"
19 | ],
20 | "sourceMap": false,
21 | "instrument": false,
22 | "cache": false,
23 | "check-coverage": true,
24 | "all": true
25 | }
26 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/downstream/.nycrc:
--------------------------------------------------------------------------------
1 | {
2 | "lines": 100,
3 | "statements": 100,
4 | "functions": 100,
5 | "branches": 100,
6 | "include": [
7 | "src/**/*.js"
8 | ],
9 | "exclude": [
10 | "test/int/**/*.test.js",
11 | "test/unit/**/*.test.js"
12 | ],
13 | "require": [],
14 | "reporter": [
15 | "text",
16 | "lcov",
17 | "html",
18 | "text-summary"
19 | ],
20 | "sourceMap": false,
21 | "instrument": false,
22 | "cache": false,
23 | "check-coverage": true,
24 | "all": true
25 | }
26 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/upstream/.nycrc:
--------------------------------------------------------------------------------
1 | {
2 | "lines": 100,
3 | "statements": 100,
4 | "functions": 100,
5 | "branches": 100,
6 | "include": [
7 | "src/**/*.js"
8 | ],
9 | "exclude": [
10 | "test/int/**/*.test.js",
11 | "test/unit/**/*.test.js"
12 | ],
13 | "require": [],
14 | "reporter": [
15 | "text",
16 | "lcov",
17 | "html",
18 | "text-summary"
19 | ],
20 | "sourceMap": false,
21 | "instrument": false,
22 | "cache": false,
23 | "check-coverage": true,
24 | "all": true
25 | }
26 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/.nycrc:
--------------------------------------------------------------------------------
1 | {
2 | "lines": 100,
3 | "statements": 100,
4 | "functions": 100,
5 | "branches": 100,
6 | "include": [
7 | "src/**/*.js"
8 | ],
9 | "exclude": [
10 | "test/int/**/*.test.js",
11 | "test/unit/**/*.test.js"
12 | ],
13 | "require": [],
14 | "reporter": [
15 | "text",
16 | "lcov",
17 | "html",
18 | "text-summary"
19 | ],
20 | "sourceMap": false,
21 | "instrument": false,
22 | "cache": false,
23 | "check-coverage": true,
24 | "all": true
25 | }
26 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-bff/.nycrc:
--------------------------------------------------------------------------------
1 | {
2 | "lines": 100,
3 | "statements": 100,
4 | "functions": 100,
5 | "branches": 100,
6 | "include": [
7 | "src/**/*.js"
8 | ],
9 | "exclude": [
10 | "test/int/**/*.test.js",
11 | "test/unit/**/*.test.js"
12 | ],
13 | "require": [],
14 | "reporter": [
15 | "text",
16 | "lcov",
17 | "html",
18 | "text-summary"
19 | ],
20 | "sourceMap": false,
21 | "instrument": false,
22 | "cache": false,
23 | "check-coverage": true,
24 | "all": true
25 | }
26 |
--------------------------------------------------------------------------------
/ch8/timeout-retry/handler.js:
--------------------------------------------------------------------------------
1 | const aws = require('aws-sdk');
2 | const uuid = require('uuid');
3 |
4 | module.exports.command = (request, context, callback) => {
5 | console.log('request: %j', request);
6 |
7 | const db = new aws.DynamoDB.DocumentClient({
8 | httpOptions: { timeout: 1000 },
9 | logger: console,
10 | // logger: { log: msg => debug(msg) },
11 | });
12 |
13 | const params = {
14 | TableName: process.env.TABLE_NAME,
15 | Item: {
16 | id: uuid.v4(),
17 | ...request,
18 | },
19 | };
20 |
21 | db.put(params, callback);
22 | };
23 |
--------------------------------------------------------------------------------
/ch2/data-lake-es/README.md:
--------------------------------------------------------------------------------
1 | # Indexing the data lake
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch2/data-lake-es --path cncb-data-lake-es
5 | 2. cd cncb-data-lake-es
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. publish an event from a separate terminal
10 | * cd ../cncb-event-stream
11 | * sls invoke -r us-east-1 -f publish -s $MY_STAGE -d '{"type":"thing-created"}'
12 | 7. sls logs -f transformer -r us-east-1 -s $MY_STAGE
13 | 8. npm run rm:lcl -- -s $MY_STAGE
14 |
--------------------------------------------------------------------------------
/ch2/data-lake-es/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-data-lake-es",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.211.0",
12 | "bluebird": "^3.5.1",
13 | "serverless": "^1.26.0",
14 | "serverless-pseudo-parameters": "1.4.2"
15 | },
16 | "dependencies": {
17 | "elasticsearch": "^14.2.1",
18 | "http-aws-es": "^4.0.0",
19 | "uuid": "3.2.1"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ch2/data-lake-s3/README.md:
--------------------------------------------------------------------------------
1 | # Creating a data lake
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch2/data-lake-s3 --path cncb-data-lake-s3
5 | 2. cd cncb-data-lake-s3
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. publish an event from a separate terminal
10 | * cd ../cncb-event-stream
11 | * sls invoke -r us-east-1 -f publish -s $MY_STAGE -d '{"type":"thing-created"}'
12 | 7. sls logs -f transformer -r us-east-1 -s $MY_STAGE
13 | 8. npm run rm:lcl -- -s $MY_STAGE
14 |
--------------------------------------------------------------------------------
/ch4/cdn-site/dist/phenomic/content/posts/item/fifth-post.json:
--------------------------------------------------------------------------------
1 | {"filename":"fifth-post.md","title":"Fifth post","date":"2017-01-05","layout":"hero","body":{"t":"div","c":[{"t":"p","c":["Another post that have a ",{"t":"a","p":{"href":"../first-post/"},"c":["link to the first one"]},"."]},"\n",{"t":"p","c":["An wrong link to ",{"t":"a","p":{"href":"../unknown-post/"},"c":["a post that does not exist"]}," and another one\nto ",{"t":"a","p":{"href":"/unknown-page/"},"c":["a page that does not exist"]},"."]},"\n",{"t":"p","c":["Here is an ",{"t":"a","p":{"href":"http://phenomic.io"},"c":["external link"]},"."]}]}}
--------------------------------------------------------------------------------
/ch10/regional-health-check/README.md:
--------------------------------------------------------------------------------
1 | # Creating a regional health check
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch10/regional-health-check --path cncb-regional-health-check
5 | 2. cd cncb-regional-health-check
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl:e -- -s $MY_STAGE
9 | 6. npm run dp:lcl:w -- -s $MY_STAGE
10 | 7. curl -v https://xyz.execute-api.us-east-1.amazonaws.com/$MY_STAGE/check
11 | 8. curl -v https://zyx.execute-api.us-west-2.amazonaws.com/$MY_STAGE/check
12 | 9. npm run rm:lcl -- -s $MY_STAGE
13 |
--------------------------------------------------------------------------------
/ch3/bff-rest-search/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-bff-rest-search",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0",
13 | "serverless-pseudo-parameters": "^1.4.2"
14 | },
15 | "dependencies": {
16 | "elasticsearch": "^14.2.2",
17 | "highland": "^2.11.1",
18 | "http-aws-es": "^4.0.0",
19 | "uuid": "^3.1.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ch1/deploy-spa/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-deploy-spa",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "react-scripts start",
7 | "build": "react-scripts build",
8 | "test": "sls package -r us-east-1 -s test",
9 | "dp:lcl": "sls deploy -v -r us-east-1",
10 | "rm:lcl": "sls remove -r us-east-1"
11 | },
12 | "dependencies": {
13 | "react": "16.2.0",
14 | "react-dom": "16.2.0"
15 | },
16 | "devDependencies": {
17 | "react-scripts": "1.1.1",
18 | "serverless": "1.26.0",
19 | "serverless-spa-deploy": "^1.0.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ch2/event-first/README.md:
--------------------------------------------------------------------------------
1 | # Applying the event-first variant of the event sourcing pattern
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch2/event-first --path cncb-event-first
5 | 2. cd cncb-event-first
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -r us-east-1 -f submit -s $MY_STAGE -d '{"id":"11111111-1111-1111-1111-111111111111","name":"thing one","kind":"other"}'
10 | 7. sls logs -f submit -r us-east-1 -s $MY_STAGE
11 | 8. npm run rm:lcl -- -s $MY_STAGE
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ch2/materialized-view-es/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-materialized-view-es",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0",
13 | "serverless-pseudo-parameters": "^1.4.2"
14 | },
15 | "dependencies": {
16 | "elasticsearch": "^14.2.2",
17 | "highland": "^2.11.1",
18 | "http-aws-es": "^4.0.0",
19 | "uuid": "^3.1.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ch4/cdn-dns/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-cdn-dns
2 |
3 | provider:
4 | name: aws
5 |
6 | plugins:
7 | - serverless-spa-deploy
8 | - serverless-spa-config
9 |
10 | custom:
11 | spa:
12 | files:
13 | - source: ./build
14 | globs: '**/*'
15 | headers:
16 | CacheControl: max-age=31536000 # 1 year
17 | - source: ./build
18 | globs: 'index.html'
19 | headers:
20 | CacheControl: max-age=300 # 5 minutes
21 | dns:
22 | hostedZoneId: Z1234567890123
23 | domainName: example.com
24 | endpoint: app.${self:custom.dns.domainName}
25 |
--------------------------------------------------------------------------------
/ch9/dynamodb-autoscaling/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-dynamodb-autoscaling",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -v -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -v -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0",
13 | "serverless-dynamodb-autoscaling-plugin": "^1.0.0"
14 | },
15 | "dependencies": {
16 | "bluebird": "^3.5.1",
17 | "highland": "^2.13.0",
18 | "moment": "^2.22.1",
19 | "uuid": "^3.2.1"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ch5/graphql-jwt/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-graphql-jwt",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "graphql": "^0.13.2",
16 | "graphql-errors": "^2.1.0",
17 | "graphql-server-lambda": "^1.3.6",
18 | "graphql-tools": "^3.0.0",
19 | "lodash": "^4.17.10",
20 | "uuid": "^3.1.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ch6/unit-testing/src/connector/stream.js:
--------------------------------------------------------------------------------
1 | /* eslint import/no-extraneous-dependencies: ["error", {"devDependencies": true}] */
2 | import { Kinesis } from 'aws-sdk';
3 |
4 | class Connector {
5 | constructor(streamName) {
6 | this.streamName = streamName;
7 | this.stream = new Kinesis();
8 | }
9 |
10 | publish(event) {
11 | const params = {
12 | StreamName: this.streamName,
13 | PartitionKey: event.partitionKey,
14 | Data: Buffer.from(JSON.stringify(event)),
15 | };
16 |
17 | return this.stream.putRecord(params).promise();
18 | }
19 | }
20 |
21 | export default Connector;
22 |
--------------------------------------------------------------------------------
/ch3/bff-graphql-crud/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-bff-graphql-crud",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "graphql": "^0.13.2",
16 | "graphql-server-lambda": "^1.3.6",
17 | "graphql-tools": "^3.0.0",
18 | "highland": "^2.11.1",
19 | "lodash": "^4.17.10",
20 | "uuid": "^3.1.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ch6/integration-testing/src/connector/stream.js:
--------------------------------------------------------------------------------
1 | /* eslint import/no-extraneous-dependencies: ["error", {"devDependencies": true}] */
2 | import { Kinesis } from 'aws-sdk';
3 |
4 | class Connector {
5 | constructor(streamName) {
6 | this.streamName = streamName;
7 | this.stream = new Kinesis();
8 | }
9 |
10 | publish(event) {
11 | const params = {
12 | StreamName: this.streamName,
13 | PartitionKey: event.partitionKey,
14 | Data: Buffer.from(JSON.stringify(event)),
15 | };
16 |
17 | return this.stream.putRecord(params).promise();
18 | }
19 | }
20 |
21 | export default Connector;
22 |
--------------------------------------------------------------------------------
/ch6/unit-testing/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "transform-runtime",
4 | [
5 | "transform-async-to-module-method",
6 | {
7 | "module": "bluebird",
8 | "method": "coroutine"
9 | }
10 | ]
11 | ],
12 | "presets": [
13 | [
14 | "env", {
15 | "useBuiltIns": true,
16 | "debug": false
17 | }],
18 | "stage-2"
19 | ],
20 | "env": {
21 | "test": {
22 | "plugins": [
23 | "istanbul"
24 | ]
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ch2/replaying-events/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-replaying-events",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "replay": "node index.js",
7 | "test": "sls package -r us-east-1",
8 | "dp:lcl": "sls deploy -v -r us-east-1",
9 | "rm:lcl": "sls remove -r us-east-1"
10 | },
11 | "devDependencies": {
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "aws-sdk": "^2.45.0",
16 | "bluebird": "^3.5.0",
17 | "debug": "^2.6.4",
18 | "highland": "^2.11.1",
19 | "lodash": "^4.17.4",
20 | "moment": "^2.18.1",
21 | "yargs": "^7.1.0"
22 | }
23 | }
--------------------------------------------------------------------------------
/ch4/cdn-dns/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import logo from './logo.svg';
3 | import './App.css';
4 |
5 | class App extends Component {
6 | render() {
7 | return (
8 |
9 |
10 |
11 | Welcome to React
12 |
13 |
14 | To get started, edit src/App.js and save to reload.
15 |
16 |
17 | );
18 | }
19 | }
20 |
21 | export default App;
22 |
--------------------------------------------------------------------------------
/ch4/cdn-spa/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import logo from './logo.svg';
3 | import './App.css';
4 |
5 | class App extends Component {
6 | render() {
7 | return (
8 |
9 |
10 |
11 | Welcome to React
12 |
13 |
14 | To get started, edit src/App.js and save to reload.
15 |
16 |
17 | );
18 | }
19 | }
20 |
21 | export default App;
22 |
--------------------------------------------------------------------------------
/ch6/integration-testing/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "transform-runtime",
4 | [
5 | "transform-async-to-module-method",
6 | {
7 | "module": "bluebird",
8 | "method": "coroutine"
9 | }
10 | ]
11 | ],
12 | "presets": [
13 | [
14 | "env", {
15 | "useBuiltIns": true,
16 | "debug": false
17 | }],
18 | "stage-2"
19 | ],
20 | "env": {
21 | "test": {
22 | "plugins": [
23 | "istanbul"
24 | ]
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ch1/deploy-spa/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import logo from './logo.svg';
3 | import './App.css';
4 |
5 | class App extends Component {
6 | render() {
7 | return (
8 |
9 |
10 |
11 | Welcome to React
12 |
13 |
14 | To get started, edit src/App.js and save to reload.
15 |
16 |
17 | );
18 | }
19 | }
20 |
21 | export default App;
22 |
--------------------------------------------------------------------------------
/ch2/db-first-dynamodb/README.md:
--------------------------------------------------------------------------------
1 | # Applying the database-first variant of the event sourcing pattern with DynamoDB
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch2/db-first-dynamodb --path cncb-db-first-dynamodb
5 | 2. cd cncb-db-first-dynamodb
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -r us-east-1 -f command -s $MY_STAGE -d '{"name":"thing one"}'
10 | 7. sls logs -f command -r us-east-1 -s $MY_STAGE
11 | 8. sls logs -f trigger -r us-east-1 -s $MY_STAGE
12 | 9. npm run rm:lcl -- -s $MY_STAGE
13 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "transform-runtime",
4 | [
5 | "transform-async-to-module-method",
6 | {
7 | "module": "bluebird",
8 | "method": "coroutine"
9 | }
10 | ]
11 | ],
12 | "presets": [
13 | [
14 | "env", {
15 | "useBuiltIns": true,
16 | "debug": false
17 | }],
18 | "stage-2"
19 | ],
20 | "env": {
21 | "test": {
22 | "plugins": [
23 | "istanbul"
24 | ]
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/src/connector/stream.js:
--------------------------------------------------------------------------------
1 | /* eslint import/no-extraneous-dependencies: ["error", {"devDependencies": true}] */
2 | import { Kinesis } from 'aws-sdk';
3 |
4 | class Connector {
5 | constructor(streamName) {
6 | this.streamName = streamName;
7 | this.stream = new Kinesis();
8 | }
9 |
10 | publish(event) {
11 | const params = {
12 | StreamName: this.streamName,
13 | PartitionKey: event.partitionKey,
14 | Data: Buffer.from(JSON.stringify(event)),
15 | };
16 |
17 | return this.stream.putRecord(params).promise();
18 | }
19 | }
20 |
21 | export default Connector;
22 |
--------------------------------------------------------------------------------
/ch5/graphql-jwt/schema/thing/model.js:
--------------------------------------------------------------------------------
1 | const uuid = require('uuid');
2 | const { merge } = require('lodash');
3 |
4 | class Thing {
5 |
6 | constructor(connector) {
7 | this.connector = connector;
8 | }
9 |
10 | getById(id) {
11 | return this.connector.getById(id);
12 | }
13 |
14 | queryByName(name, limit, cursor) {
15 | return this.connector.queryByName(name, cursor, limit);
16 | }
17 |
18 | save(id, body) {
19 | id = id ? id : uuid.v4();
20 | return this.connector.save(id, body);
21 | }
22 |
23 | delete(id) {
24 | return this.connector.delete(id);
25 | }
26 | }
27 |
28 | module.exports = Thing
--------------------------------------------------------------------------------
/ch6/contract-testing-async/upstream/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "transform-runtime",
4 | [
5 | "transform-async-to-module-method",
6 | {
7 | "module": "bluebird",
8 | "method": "coroutine"
9 | }
10 | ]
11 | ],
12 | "presets": [
13 | [
14 | "env", {
15 | "useBuiltIns": true,
16 | "debug": false
17 | }],
18 | "stage-2"
19 | ],
20 | "env": {
21 | "test": {
22 | "plugins": [
23 | "istanbul"
24 | ]
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/upstream/src/connector/stream.js:
--------------------------------------------------------------------------------
1 | /* eslint import/no-extraneous-dependencies: ["error", {"devDependencies": true}] */
2 | import { Kinesis } from 'aws-sdk';
3 |
4 | class Connector {
5 | constructor(streamName) {
6 | this.streamName = streamName;
7 | this.stream = new Kinesis();
8 | }
9 |
10 | publish(event) {
11 | const params = {
12 | StreamName: this.streamName,
13 | PartitionKey: event.partitionKey,
14 | Data: Buffer.from(JSON.stringify(event)),
15 | };
16 |
17 | return this.stream.putRecord(params).promise();
18 | }
19 | }
20 |
21 | export default Connector;
22 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "transform-runtime",
4 | [
5 | "transform-async-to-module-method",
6 | {
7 | "module": "bluebird",
8 | "method": "coroutine"
9 | }
10 | ]
11 | ],
12 | "presets": [
13 | [
14 | "env", {
15 | "useBuiltIns": true,
16 | "debug": false
17 | }],
18 | "stage-2"
19 | ],
20 | "env": {
21 | "test": {
22 | "plugins": [
23 | "istanbul"
24 | ]
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-bff/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "transform-runtime",
4 | [
5 | "transform-async-to-module-method",
6 | {
7 | "module": "bluebird",
8 | "method": "coroutine"
9 | }
10 | ]
11 | ],
12 | "presets": [
13 | [
14 | "env", {
15 | "useBuiltIns": true,
16 | "debug": false
17 | }],
18 | "stage-2"
19 | ],
20 | "env": {
21 | "test": {
22 | "plugins": [
23 | "istanbul"
24 | ]
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ch1/create-stream-processor/README.md:
--------------------------------------------------------------------------------
1 | # Creating a stream processor
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch1/create-stream-processor --path cncb-create-stream-processor
5 | 2. cd cncb-create-stream-processor
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. publish an event from a separate terminal
10 | * cd ../cncb-event-stream
11 | * sls invoke -r us-east-1 -f publish -s $MY_STAGE -d '{"type":"thing-created"}'
12 | 7. sls logs -f listener -r us-east-1 -s $MY_STAGE
13 | 8. npm run rm:lcl -- -s $MY_STAGE
14 |
--------------------------------------------------------------------------------
/ch10/latency-based-routing/README.md:
--------------------------------------------------------------------------------
1 | # Implementing latency based routing
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch10/regional-health-check --path cncb-regional-health-check
5 | 2. cd cncb-regional-health-check
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl:w -- -s $MY_STAGE
9 | 6. curl -v https://$MY_STAGE-cncb-latency-based-routing.example.com/$MY_STAGE/hello
10 | 7. npm run dp:lcl:e -- -s $MY_STAGE
11 | 8. curl -v https://cncb-latency-based-routing.example.com/hello
12 | 9. npm run rm:lcl:w -- -s $MY_STAGE
13 | 10. npm run rm:lcl:e -- -s $MY_STAGE
14 |
--------------------------------------------------------------------------------
/ch4/cdn-dns/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-cdn-dns",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "react-scripts start",
7 | "build": "react-scripts build",
8 | "test": "sls package -r us-east-1 -s test",
9 | "dp:lcl": "sls deploy -v -r us-east-1",
10 | "rm:lcl": "sls remove -r us-east-1"
11 | },
12 | "dependencies": {
13 | "react": "16.2.0",
14 | "react-dom": "16.2.0"
15 | },
16 | "devDependencies": {
17 | "react-scripts": "1.1.1",
18 | "serverless": "1.26.0",
19 | "serverless-spa-config": "1.0.2",
20 | "serverless-spa-deploy": "1.0.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ch4/cdn-spa/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-cdn-spa",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "react-scripts start",
7 | "build": "react-scripts build",
8 | "test": "sls package -r us-east-1 -s test",
9 | "dp:lcl": "sls deploy -v -r us-east-1",
10 | "rm:lcl": "sls remove -r us-east-1"
11 | },
12 | "dependencies": {
13 | "react": "16.2.0",
14 | "react-dom": "16.2.0"
15 | },
16 | "devDependencies": {
17 | "react-scripts": "1.1.1",
18 | "serverless": "1.26.0",
19 | "serverless-spa-config": "1.0.2",
20 | "serverless-spa-deploy": "1.0.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/downstream/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "transform-runtime",
4 | [
5 | "transform-async-to-module-method",
6 | {
7 | "module": "bluebird",
8 | "method": "coroutine"
9 | }
10 | ]
11 | ],
12 | "presets": [
13 | [
14 | "env", {
15 | "useBuiltIns": true,
16 | "debug": false
17 | }],
18 | "stage-2"
19 | ],
20 | "env": {
21 | "test": {
22 | "plugins": [
23 | "istanbul"
24 | ]
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ch9/session-consistency/service/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-session-consistency-service",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl": "sls deploy -v -r us-east-1",
8 | "rm:lcl": "sls remove -r us-east-1"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "graphql": "^0.13.2",
16 | "graphql-server-lambda": "^1.3.6",
17 | "graphql-tools": "^3.0.0",
18 | "highland": "^2.11.1",
19 | "lodash": "^4.17.10",
20 | "uuid": "^3.1.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ch5/dr/README.md:
--------------------------------------------------------------------------------
1 | # Replicating the data lake for disaster recovery
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch5/dr --path cncb-dr
5 | 2. cd cncb-dr/recovery-account
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. cd ../src1-account
10 | 7. npm install
11 | 8. npm test -- -s $MY_STAGE
12 | 9. npm run dp:lcl -- -s $MY_STAGE
13 | 10. sls invoke -r us-east-1 -f load -s $MY_STAGE
14 | 11. review source and target buckets
15 | 12. npm run rm:lcl -- -s $MY_STAGE
16 | 13. cd ../recovery-account
17 | 14. npm run rm:lcl -- -s $MY_STAGE
18 |
--------------------------------------------------------------------------------
/ch7/synthetics/README.md:
--------------------------------------------------------------------------------
1 | # Creating synthetic transaction tests
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch5/cognito-signin --path cncb-cognito-signin
5 | 2. cd cncb-cognito-signin
6 | 3. npm install
7 | 4. Update src/configuration.js
8 | 4. npm start
9 | 5. npm test
10 | 6. npm run build
11 | 7. npm run dp:lcl -- -s $MY_STAGE
12 | 8. browse http://cncb-cognito-signin-$MY_STAGE-websitebucket-xxxx.s3-website-us-east-1.amazonaws.com
13 | 9. Click Sign Up and complete form
14 | 10. Click Sign Out
15 | 11. Click Sign In and complete form
16 | 12. npm run rm:lcl -- -s $MY_STAGE
17 |
--------------------------------------------------------------------------------
/ch1/create-stream-processor/handler.js:
--------------------------------------------------------------------------------
1 | const _ = require('highland');
2 |
3 | module.exports.listener = (event, context, cb) => {
4 | console.log('event: %j', event);
5 |
6 | _(event.Records)
7 | .map(recordToEvent)
8 | .tap(printEvent)
9 | .filter(forThingCreated)
10 | .collect()
11 | .tap(printCount)
12 | .toCallback(cb);
13 | };
14 |
15 | const recordToEvent = r => JSON.parse(Buffer.from(r.kinesis.data, 'base64'));
16 |
17 | const forThingCreated = e => e.type === 'thing-created';
18 |
19 | const printEvent = e => console.log('event: %j', e);
20 |
21 | const printCount = events => console.log('count: %d', events.length);
22 |
--------------------------------------------------------------------------------
/ch6/integration-testing/fixtures/dynamodb.us-east-1.amazonaws.com-443/save:
--------------------------------------------------------------------------------
1 | POST /
2 | content-type: application/x-amz-json-1.0
3 | x-amz-target: DynamoDB_20120810.PutItem
4 | host: dynamodb.us-east-1.amazonaws.com
5 | body: {\"TableName\":\"stg-cncb-integration-testing-things\",\"Item\":{\"id\":{\"S\":\"00000000-0000-0000-0000-000000000000\"},\"name\":{\"S\":\"thing0\"}}}
6 |
7 | HTTP/1.1 200 OK
8 | server: Server
9 | date: Fri, 15 Jun 2018 05:59:44 GMT
10 | content-type: application/x-amz-json-1.0
11 | content-length: 2
12 | connection: keep-alive
13 | x-amzn-requestid: ECUGR6AOBDC45NLA4SI4UMN4RRVV4KQNSO5AEMVJF66Q9ASUAAJG
14 | x-amz-crc32: 2745614147
15 |
16 | {}
--------------------------------------------------------------------------------
/ch9/tuning-faas/src/get/index.js:
--------------------------------------------------------------------------------
1 | import { response200, response404, response500 } from '../utils';
2 | import Connector from '../connector/db';
3 |
4 | export class Handler {
5 | constructor(tableName) {
6 | this.connector = new Connector(tableName);
7 | }
8 |
9 | handle(request) {
10 | const { id } = request.pathParameters;
11 | return this.connector.getById(id);
12 | }
13 | }
14 |
15 | export const handle = (request, context, cb) => {
16 | new Handler(process.env.TABLE_NAME)
17 | .handle(request)
18 | .then(data => (data ?
19 | response200(cb, data) :
20 | response404(cb)))
21 | .catch(response500(cb));
22 | };
23 |
--------------------------------------------------------------------------------
/ch6/unit-testing/src/get/index.js:
--------------------------------------------------------------------------------
1 | import { response200, response404, response500 } from '../utils';
2 | import Connector from '../connector/db';
3 |
4 | export class Handler {
5 | constructor(tableName) {
6 | this.connector = new Connector(tableName);
7 | }
8 |
9 | handle(request) {
10 | const { id } = request.pathParameters;
11 | return this.connector.getById(id);
12 | }
13 | }
14 |
15 | export const handle = (request, context, cb) => {
16 | new Handler(process.env.TABLE_NAME)
17 | .handle(request)
18 | .then(data => (data ?
19 | response200(cb, data) :
20 | response404(cb)))
21 | .catch(response500(cb));
22 | };
23 |
--------------------------------------------------------------------------------
/ch7/custom-metrics/handler.js:
--------------------------------------------------------------------------------
1 | const { monitor, count } = require('serverless-datadog-metrics');
2 | const debug = require('debug')('handler');
3 |
4 | module.exports.hello = monitor((request, context, callback) => {
5 | debug('request: %j', request);
6 | debug('context: %j', context);
7 |
8 | count('hello.count', 1);
9 |
10 | const response = {
11 | statusCode: 200,
12 | headers: {
13 | 'Access-Control-Allow-Origin': '*',
14 | },
15 | body: JSON.stringify({
16 | message: 'JavaScript Cloud Native Development Cookbook! Your function executed successfully!',
17 | }),
18 | };
19 |
20 | callback(null, response);
21 | });
22 |
--------------------------------------------------------------------------------
/ch9/tuning-faas/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | [
4 | "transform-async-to-module-method",
5 | {
6 | "module": "bluebird",
7 | "method": "coroutine"
8 | }
9 | ]
10 | ],
11 | "presets": [
12 | [
13 | "env", {
14 | "node": "8.10",
15 | "useBuiltIns": true,
16 | "debug": false
17 | }],
18 | "stage-2"
19 | ],
20 | "env": {
21 | "test": {
22 | "plugins": [
23 | "istanbul",
24 | "transform-runtime"
25 | ]
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ch3/event-orchestration/serverless.yml:
--------------------------------------------------------------------------------
1 | service: cncb-event-orchestration
2 |
3 | provider:
4 | name: aws
5 | runtime: nodejs8.10
6 | iamRoleStatements:
7 | - Effect: Allow
8 | Action:
9 | - kinesis:PutRecord
10 | Resource: ${cf:cncb-event-stream-${opt:stage}.streamArn}
11 |
12 | functions:
13 | listener:
14 | handler: handler.listener
15 | events:
16 | - stream:
17 | type: kinesis
18 | arn: ${cf:cncb-event-stream-${opt:stage}.streamArn}
19 | batchSize: 100
20 | startingPosition: TRIM_HORIZON
21 | environment:
22 | STREAM_NAME: ${cf:cncb-event-stream-${opt:stage}.streamName}
23 |
--------------------------------------------------------------------------------
/ch5/graphql-jwt/schema/directives.js:
--------------------------------------------------------------------------------
1 | const { get, intersection } = require('lodash');
2 | const { UserError } = require('graphql-errors');
3 |
4 | const getGroups = ctx => get(ctx.event, 'requestContext.authorizer.claims.cognito:groups', '');
5 |
6 | const directiveResolvers = {
7 | hasRole: (next, source, { roles }, ctx) => {
8 | const groups = getGroups(ctx).split(',');
9 | if (groups && intersection(groups, roles).length > 0) {
10 | return next();
11 | }
12 | console.log('hasRole: (%s) does not intersect (%s)', groups, roles);
13 | throw new UserError('Access Denied');
14 | },
15 | }
16 |
17 | module.exports = { directiveResolvers };
18 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/fixtures/dynamodb.us-east-1.amazonaws.com-443/save:
--------------------------------------------------------------------------------
1 | POST /
2 | content-type: application/x-amz-json-1.0
3 | x-amz-target: DynamoDB_20120810.PutItem
4 | host: dynamodb.us-east-1.amazonaws.com
5 | body: {\"TableName\":\"stg-cncb-contract-testing-sync-things\",\"Item\":{\"id\":{\"S\":\"00000000-0000-0000-0000-000000000000\"},\"name\":{\"S\":\"thing0\"}}}
6 |
7 | HTTP/1.1 200 OK
8 | server: Server
9 | date: Sun, 17 Jun 2018 21:26:46 GMT
10 | content-type: application/x-amz-json-1.0
11 | content-length: 2
12 | connection: keep-alive
13 | x-amzn-requestid: MI2E1841TID76J3RE8ITB2RIPBVV4KQNSO5AEMVJF66Q9ASUAAJG
14 | x-amz-crc32: 2745614147
15 |
16 | {}
--------------------------------------------------------------------------------
/ch6/integration-testing/src/get/index.js:
--------------------------------------------------------------------------------
1 | import { response200, response404, response500 } from '../utils';
2 | import Connector from '../connector/db';
3 |
4 | export class Handler {
5 | constructor(tableName) {
6 | this.connector = new Connector(tableName);
7 | }
8 |
9 | handle(request) {
10 | const { id } = request.pathParameters;
11 | return this.connector.getById(id);
12 | }
13 | }
14 |
15 | export const handle = (request, context, cb) => {
16 | new Handler(process.env.TABLE_NAME)
17 | .handle(request)
18 | .then(data => (data ?
19 | response200(cb, data) :
20 | response404(cb)))
21 | .catch(response500(cb));
22 | };
23 |
--------------------------------------------------------------------------------
/ch7/event-metrics/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-event-metrics",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -v -r us-east-1 -s test --account cncb",
7 | "dp:lcl": "sls deploy -v -r us-east-1 --account cncb",
8 | "rm:lcl": "sls remove -v -r us-east-1 --account cncb"
9 | },
10 | "devDependencies": {
11 | "aws-sdk": "^2.218.1",
12 | "serverless": "1.26.0"
13 | },
14 | "dependencies": {
15 | "bluebird": "^3.5.1",
16 | "debug": "^3.1.0",
17 | "highland": "^2.13.0",
18 | "moment": "^2.22.1",
19 | "serverless-datadog-metrics": "^1.0.1",
20 | "uuid": "^3.2.1"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/src/get/index.js:
--------------------------------------------------------------------------------
1 | import { response200, response404, response500 } from '../utils';
2 | import Connector from '../connector/db';
3 |
4 | export class Handler {
5 | constructor(tableName) {
6 | this.connector = new Connector(tableName);
7 | }
8 |
9 | handle(request) {
10 | const { id } = request.pathParameters;
11 | return this.connector.getById(id);
12 | }
13 | }
14 |
15 | export const handle = (request, context, cb) => {
16 | new Handler(process.env.TABLE_NAME)
17 | .handle(request)
18 | .then(data => (data ?
19 | response200(cb, data) :
20 | response404(cb)))
21 | .catch(response500(cb));
22 | };
23 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/src/get/index.js:
--------------------------------------------------------------------------------
1 | import { response200, response404, response500 } from '../utils';
2 | import Connector from '../connector/db';
3 |
4 | export class Handler {
5 | constructor(tableName) {
6 | this.connector = new Connector(tableName);
7 | }
8 |
9 | handle(request) {
10 | const { id } = request.pathParameters;
11 | return this.connector.getById(id);
12 | }
13 | }
14 |
15 | export const handle = (request, context, cb) => {
16 | new Handler(process.env.TABLE_NAME)
17 | .handle(request)
18 | .then(data => (data ?
19 | response200(cb, data) :
20 | response404(cb)))
21 | .catch(response500(cb));
22 | };
23 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-bff/src/get/index.js:
--------------------------------------------------------------------------------
1 | import { response200, response404, response500 } from '../utils';
2 | import Connector from '../connector/db';
3 |
4 | export class Handler {
5 | constructor(tableName) {
6 | this.connector = new Connector(tableName);
7 | }
8 |
9 | handle(request) {
10 | const { id } = request.pathParameters;
11 | return this.connector.getById(id);
12 | }
13 | }
14 |
15 | export const handle = (request, context, cb) => {
16 | new Handler(process.env.TABLE_NAME)
17 | .handle(request)
18 | .then(data => (data ?
19 | response200(cb, data) :
20 | response404(cb)))
21 | .catch(response500(cb));
22 | };
23 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/downstream/src/get/index.js:
--------------------------------------------------------------------------------
1 | import { response200, response404, response500 } from '../utils';
2 | import Connector from '../connector/db';
3 |
4 | export class Handler {
5 | constructor(tableName) {
6 | this.connector = new Connector(tableName);
7 | }
8 |
9 | handle(request) {
10 | const { id } = request.pathParameters;
11 | return this.connector.getById(id);
12 | }
13 | }
14 |
15 | export const handle = (request, context, cb) => {
16 | new Handler(process.env.TABLE_NAME)
17 | .handle(request)
18 | .then(data => (data ?
19 | response200(cb, data) :
20 | response404(cb)))
21 | .catch(response500(cb));
22 | };
23 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/upstream/fixtures/dynamodb.us-east-1.amazonaws.com-443/save:
--------------------------------------------------------------------------------
1 | POST /
2 | content-type: application/x-amz-json-1.0
3 | x-amz-target: DynamoDB_20120810.PutItem
4 | host: dynamodb.us-east-1.amazonaws.com
5 | body: {\"TableName\":\"stg-cncb-contract-testing-async-upstream-things\",\"Item\":{\"id\":{\"S\":\"00000000-0000-0000-0000-000000000000\"},\"name\":{\"S\":\"thing0\"}}}
6 |
7 | HTTP/1.1 200 OK
8 | server: Server
9 | date: Wed, 20 Jun 2018 03:38:06 GMT
10 | content-type: application/x-amz-json-1.0
11 | content-length: 2
12 | connection: keep-alive
13 | x-amzn-requestid: 94BULVS95GCK7O79DT618VIL0NVV4KQNSO5AEMVJF66Q9ASUAAJG
14 | x-amz-crc32: 2745614147
15 |
16 | {}
--------------------------------------------------------------------------------
/ch3/bff-graphql-crud/schema/index.js:
--------------------------------------------------------------------------------
1 | const { merge } = require('lodash');
2 | const { makeExecutableSchema } = require('graphql-tools');
3 | const { thingTypeDefs, thingResolvers } = require('./thing');
4 |
5 | const query = `
6 | type Query {
7 | _empty: String
8 | }
9 | `;
10 |
11 | const mutation = `
12 | type Mutation {
13 | _empty: String
14 | }
15 | `;
16 |
17 | const schemaDefinition = `
18 | schema {
19 | query: Query
20 | mutation: Mutation
21 | }
22 | `;
23 |
24 | module.exports = makeExecutableSchema({
25 | typeDefs: [schemaDefinition, query, mutation, thingTypeDefs],
26 | resolvers: merge({}, thingResolvers),
27 | logger: console,
28 | });
29 |
--------------------------------------------------------------------------------
/ch3/bff-graphql-crud/schema/thing/typedefs.js:
--------------------------------------------------------------------------------
1 | module.exports = `
2 | type Thing {
3 | id: String!
4 | name: String
5 | description: String
6 | }
7 |
8 | type ThingConnection {
9 | items: [Thing!]!
10 | cursor: String
11 | }
12 |
13 | extend type Query {
14 | thing(id: String!): Thing
15 | things(name: String, limit: Int, cursor: String): ThingConnection
16 | }
17 |
18 | input ThingInput {
19 | id: String
20 | name: String!
21 | description: String
22 | }
23 |
24 | extend type Mutation {
25 | saveThing(
26 | input: ThingInput
27 | ): Thing
28 | deleteThing(
29 | id: ID!
30 | ): Thing
31 | }
32 | `;
33 |
--------------------------------------------------------------------------------
/ch5/cognito-signin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-cognito-signin",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "react-scripts start",
7 | "build": "react-scripts build",
8 | "test": "sls package -r us-east-1 -s test",
9 | "dp:lcl": "sls deploy -v -r us-east-1",
10 | "rm:lcl": "sls remove -r us-east-1"
11 | },
12 | "dependencies": {
13 | "amazon-cognito-auth-js": "1.2.4",
14 | "react": "16.3.2",
15 | "react-dom": "16.3.2"
16 | },
17 | "devDependencies": {
18 | "react-scripts": "1.1.5",
19 | "react-router-dom": "4.3.1",
20 | "serverless": "1.26.0",
21 | "serverless-spa-deploy": "^1.0.0"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/fixtures/dynamodb.us-east-1.amazonaws.com-443/save-thing0:
--------------------------------------------------------------------------------
1 | POST /
2 | content-type: application/x-amz-json-1.0
3 | x-amz-target: DynamoDB_20120810.PutItem
4 | host: dynamodb.us-east-1.amazonaws.com
5 | body: {\"TableName\":\"stg-cncb-transitive-testing-author-bff-things\",\"Item\":{\"id\":{\"S\":\"00000000-0000-0000-0000-000000000000\"},\"name\":{\"S\":\"thing0\"}}}
6 |
7 | HTTP/1.1 200 OK
8 | server: Server
9 | date: Sun, 17 Jun 2018 21:26:46 GMT
10 | content-type: application/x-amz-json-1.0
11 | content-length: 2
12 | connection: keep-alive
13 | x-amzn-requestid: MI2E1841TID76J3RE8ITB2RIPBVV4KQNSO5AEMVJF66Q9ASUAAJG
14 | x-amz-crc32: 2745614147
15 |
16 | {}
17 |
--------------------------------------------------------------------------------
/ch9/session-consistency/service/schema/index.js:
--------------------------------------------------------------------------------
1 | const { merge } = require('lodash');
2 | const { makeExecutableSchema } = require('graphql-tools');
3 | const { thingTypeDefs, thingResolvers } = require('./thing');
4 |
5 | const query = `
6 | type Query {
7 | _empty: String
8 | }
9 | `;
10 |
11 | const mutation = `
12 | type Mutation {
13 | _empty: String
14 | }
15 | `;
16 |
17 | const schemaDefinition = `
18 | schema {
19 | query: Query
20 | mutation: Mutation
21 | }
22 | `;
23 |
24 | module.exports = makeExecutableSchema({
25 | typeDefs: [schemaDefinition, query, mutation, thingTypeDefs],
26 | resolvers: merge({}, thingResolvers),
27 | logger: console,
28 | });
29 |
--------------------------------------------------------------------------------
/ch9/session-consistency/service/schema/thing/typedefs.js:
--------------------------------------------------------------------------------
1 | module.exports = `
2 | type Thing {
3 | id: String!
4 | name: String
5 | description: String
6 | }
7 |
8 | type ThingConnection {
9 | items: [Thing!]!
10 | cursor: String
11 | }
12 |
13 | extend type Query {
14 | thing(id: String!): Thing
15 | things(name: String, limit: Int, cursor: String): ThingConnection
16 | }
17 |
18 | input ThingInput {
19 | id: String
20 | name: String!
21 | description: String
22 | }
23 |
24 | extend type Mutation {
25 | saveThing(
26 | input: ThingInput
27 | ): Thing
28 | deleteThing(
29 | id: ID!
30 | ): Thing
31 | }
32 | `;
33 |
--------------------------------------------------------------------------------
/ch9/session-consistency/spa/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 |
6 | import { ApolloProvider } from "react-apollo";
7 | import { ApolloClient, HttpLink, InMemoryCache } from "apollo-boost";
8 |
9 | const client = new ApolloClient({
10 | link: new HttpLink({
11 | // CHANGE ME
12 | uri: 'https://r281sep4o7.execute-api.us-east-1.amazonaws.com/john/graphql',
13 | }),
14 | cache: new InMemoryCache(),
15 | });
16 |
17 | ReactDOM.render(
18 |
19 |
20 | ,
21 | document.getElementById('root')
22 | );
23 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-bff/test/int/upstream-author-bff/e2e.test.js:
--------------------------------------------------------------------------------
1 | import 'mocha';
2 | import * as aws from 'aws-sdk';
3 |
4 | import { handle } from '../../../src/listener';
5 |
6 | const relay = require('baton-event-relay');
7 | require('baton-vcr-replay-for-aws-sdk');
8 |
9 | describe('e2e/upstream-author-bff', () => {
10 | before(() => {
11 | process.env.TABLE_NAME = 'stg-cncb-transitive-testing-customer-bff-things';
12 | aws.config.update({ region: 'us-east-1' });
13 | });
14 |
15 | it('should process the thing0-created event', (done) => {
16 | const rec = relay('./fixtures/upstream-author-bff/thing0-created');
17 | handle(rec.event, {}, done);
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/ch5/cognito-authorizer/README.md:
--------------------------------------------------------------------------------
1 | # Securing an API gateway with OAuth 2.0
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch5/cognito-authorizer --path cncb-cognito-authorizer
5 | 2. cd cncb-cognito-authorizer
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. curl -v https://xyz.execute-api.us-east-1.amazonaws.com/$MY_STAGE/hello | json_pp
10 | 7. export CNCB_TOKEN=1234567890.1234567890
11 | 8. curl -v -H "Authorization: Bearer $CNCB_TOKEN" https://xyz.execute-api.us-east-1.amazonaws.com/$MY_STAGE/hello | json_pp
12 | 9. sls logs -f hello -r us-east-1 -s $MY_STAGE
13 | 10. npm run rm:lcl -- -s $MY_STAGE
14 |
--------------------------------------------------------------------------------
/ch6/integration-testing/fixtures/dynamodb.us-east-1.amazonaws.com-443/get:
--------------------------------------------------------------------------------
1 | POST /
2 | content-type: application/x-amz-json-1.0
3 | x-amz-target: DynamoDB_20120810.GetItem
4 | host: dynamodb.us-east-1.amazonaws.com
5 | body: {\"TableName\":\"stg-cncb-integration-testing-things\",\"Key\":{\"id\":{\"S\":\"00000000-0000-0000-0000-000000000000\"}}}
6 |
7 | HTTP/1.1 200 OK
8 | server: Server
9 | date: Sat, 16 Jun 2018 04:09:37 GMT
10 | content-type: application/x-amz-json-1.0
11 | content-length: 82
12 | connection: keep-alive
13 | x-amzn-requestid: 4IPLUULPC0GEH3BQ7GS43U9JK7VV4KQNSO5AEMVJF66Q9ASUAAJG
14 | x-amz-crc32: 3235158845
15 |
16 | {"Item":{"id":{"S":"00000000-0000-0000-0000-000000000000"},"name":{"S":"thing0"}}}
--------------------------------------------------------------------------------
/ch4/cdn-lambda/README.md:
--------------------------------------------------------------------------------
1 | # Executing code at the edge of the cloud
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch4/cdn-lambda --path cncb-cdn-lambda
5 | 2. cd cncb-cdn-lambda
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. sls invoke -r us-east-1 -f load -s $MY_STAGE -d '{"id":"44444444-7777-1111-1111-000000000000","name":"thing one"}'
10 | 7. curl -v https://xyz.cloudfront.net/things/44444444-7777-1111-1111-000000000000 | json_pp
11 | 8. curl -v -H "Authorization: Bearer 1234567890" https://xyz.cloudfront.net/things/44444444-7777-1111-1111-000000000000 | json_pp
12 | 9. npm run rm:lcl -- -s $MY_STAGE
13 |
--------------------------------------------------------------------------------
/ch6/pipeline/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | image: node:8
2 |
3 | before_script:
4 | - cp .npmrc-conf .npmrc
5 | - npm install --unsafe-perm
6 |
7 | test:
8 | stage: test
9 | script:
10 | - npm test
11 | - npm run test:int
12 |
13 | stg-east:
14 | stage: deploy
15 | variables:
16 | AWS_ACCESS_KEY_ID: $DEV_AWS_ACCESS_KEY_ID
17 | AWS_SECRET_ACCESS_KEY: $DEV_AWS_SECRET_ACCESS_KEY
18 | script:
19 | - npm run dp:stg:e
20 | except:
21 | - master
22 |
23 | production-east:
24 | stage: deploy
25 | variables:
26 | AWS_ACCESS_KEY_ID: $PROD_AWS_ACCESS_KEY_ID
27 | AWS_SECRET_ACCESS_KEY: $PROD_AWS_SECRET_ACCESS_KEY
28 | script:
29 | - npm run dp:prd:e
30 | only:
31 | - master
32 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/fixtures/dynamodb.us-east-1.amazonaws.com-443/get:
--------------------------------------------------------------------------------
1 | POST /
2 | content-type: application/x-amz-json-1.0
3 | x-amz-target: DynamoDB_20120810.GetItem
4 | host: dynamodb.us-east-1.amazonaws.com
5 | body: {\"TableName\":\"stg-cncb-contract-testing-sync-things\",\"Key\":{\"id\":{\"S\":\"00000000-0000-0000-0000-000000000000\"}}}
6 |
7 | HTTP/1.1 200 OK
8 | server: Server
9 | date: Sun, 17 Jun 2018 21:26:46 GMT
10 | content-type: application/x-amz-json-1.0
11 | content-length: 82
12 | connection: keep-alive
13 | x-amzn-requestid: AQRBJO9RV5EKDR4R7K0G9G92L7VV4KQNSO5AEMVJF66Q9ASUAAJG
14 | x-amz-crc32: 3235158845
15 |
16 | {"Item":{"id":{"S":"00000000-0000-0000-0000-000000000000"},"name":{"S":"thing0"}}}
--------------------------------------------------------------------------------
/ch6/unit-testing/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | image: node:8
2 |
3 | before_script:
4 | - cp .npmrc-conf .npmrc
5 | - npm install --unsafe-perm
6 |
7 | test:
8 | stage: test
9 | script:
10 | - npm test
11 | - npm run test:int
12 |
13 | stg-east:
14 | stage: deploy
15 | variables:
16 | AWS_ACCESS_KEY_ID: $DEV_AWS_ACCESS_KEY_ID
17 | AWS_SECRET_ACCESS_KEY: $DEV_AWS_SECRET_ACCESS_KEY
18 | script:
19 | - npm run dp:stg:e
20 | except:
21 | - master
22 |
23 | production-east:
24 | stage: deploy
25 | variables:
26 | AWS_ACCESS_KEY_ID: $PROD_AWS_ACCESS_KEY_ID
27 | AWS_SECRET_ACCESS_KEY: $PROD_AWS_SECRET_ACCESS_KEY
28 | script:
29 | - npm run dp:prd:e
30 | only:
31 | - master
32 |
--------------------------------------------------------------------------------
/ch10/dynamodb-global-table/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-dynamodb-global-table",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl:e": "sls deploy -v -r us-east-1",
8 | "dp:lcl:w": "sls deploy -v -r us-west-2",
9 | "rm:lcl:e": "sls remove -v -r us-east-1",
10 | "rm:lcl:w": "sls remove -v -r us-west-2"
11 | },
12 | "devDependencies": {
13 | "aws-sdk": "^2.218.1",
14 | "serverless": "1.26.0",
15 | "serverless-dynamodb-autoscaling-plugin": "^1.0.0",
16 | "serverless-dynamodb-global-table-plugin": "^1.0.1"
17 | },
18 | "dependencies": {
19 | "highland": "^2.11.1",
20 | "uuid": "^3.1.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ch10/round-robin-replication/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-round-robin-replication",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "test": "sls package -r us-east-1",
7 | "dp:lcl:e": "sls deploy -v -r us-east-1",
8 | "dp:lcl:w": "sls deploy -v -r us-west-2",
9 | "rm:lcl:e": "sls remove -v -r us-east-1",
10 | "rm:lcl:w": "sls remove -v -r us-west-2"
11 | },
12 | "devDependencies": {
13 | "aws-sdk": "^2.218.1",
14 | "serverless": "1.26.0",
15 | "serverless-pseudo-parameters": "^1.4.2"
16 | },
17 | "dependencies": {
18 | "elasticsearch": "^14.2.2",
19 | "highland": "^2.11.1",
20 | "http-aws-es": "^4.0.0",
21 | "uuid": "^3.1.0"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/downstream/fixtures/dynamodb.us-east-1.amazonaws.com-443/save:
--------------------------------------------------------------------------------
1 | POST /
2 | content-type: application/x-amz-json-1.0
3 | x-amz-target: DynamoDB_20120810.PutItem
4 | host: dynamodb.us-east-1.amazonaws.com
5 | body: {\"TableName\":\"stg-cncb-contract-testing-async-downstream-things\",\"Item\":{\"id\":{\"S\":\"00000000-0000-0000-0000-000000000000\"},\"name\":{\"S\":\"thing0\"},\"asOf\":{\"N\":\"1529179380000\"}}}
6 |
7 | HTTP/1.1 200 OK
8 | server: Server
9 | date: Wed, 20 Jun 2018 05:05:21 GMT
10 | content-type: application/x-amz-json-1.0
11 | content-length: 2
12 | connection: keep-alive
13 | x-amzn-requestid: B2804F055G85Q4U9QBB086EIFFVV4KQNSO5AEMVJF66Q9ASUAAJG
14 | x-amz-crc32: 2745614147
15 |
16 | {}
--------------------------------------------------------------------------------
/ch6/contract-testing-async/downstream/test/int/upstream-provider-y/contract.test.js:
--------------------------------------------------------------------------------
1 | import 'mocha';
2 | import * as aws from 'aws-sdk';
3 |
4 | import { handle } from '../../../src/listener';
5 |
6 | const relay = require('baton-event-relay');
7 |
8 | require('baton-vcr-replay-for-aws-sdk');
9 |
10 | describe('contract/upstream-provider-y', () => {
11 | before(() => {
12 | process.env.TABLE_NAME = 'stg-cncb-contract-testing-async-downstream-things';
13 | aws.config.update({ region: 'us-east-1' });
14 | });
15 |
16 | it('should process the thing-created event', (done) => {
17 | const rec = relay('./fixtures/upstream-provider-y/thing-created');
18 | handle(rec.event, {}, done);
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/ch6/feature-flag/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-feature-flag",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "react-scripts start",
7 | "build": "react-scripts build",
8 | "test": "sls package -r us-east-1 -s test",
9 | "dp:lcl": "sls deploy -v -r us-east-1",
10 | "rm:lcl": "sls remove -r us-east-1"
11 | },
12 | "dependencies": {
13 | "amazon-cognito-auth-js": "1.2.4",
14 | "lodash": "^4.17.10",
15 | "react": "16.3.2",
16 | "react-dom": "16.3.2"
17 | },
18 | "devDependencies": {
19 | "react-scripts": "1.1.5",
20 | "react-router-dom": "4.3.1",
21 | "serverless": "1.26.0",
22 | "serverless-spa-deploy": "^1.0.0"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/customer-bff/fixtures/dynamodb.us-east-1.amazonaws.com-443/save-thing0:
--------------------------------------------------------------------------------
1 | POST /
2 | content-type: application/x-amz-json-1.0
3 | x-amz-target: DynamoDB_20120810.PutItem
4 | host: dynamodb.us-east-1.amazonaws.com
5 | body: {\"TableName\":\"stg-cncb-transitive-testing-customer-bff-things\",\"Item\":{\"id\":{\"S\":\"00000000-0000-0000-0000-000000000000\"},\"name\":{\"S\":\"thing0\"},\"asOf\":{\"N\":\"1529179380000\"}}}
6 |
7 | HTTP/1.1 200 OK
8 | server: Server
9 | date: Tue, 26 Jun 2018 02:17:26 GMT
10 | content-type: application/x-amz-json-1.0
11 | content-length: 2
12 | connection: keep-alive
13 | x-amzn-requestid: 2Q2FFGLM6D11KAEKJBDH4SFK1FVV4KQNSO5AEMVJF66Q9ASUAAJG
14 | x-amz-crc32: 2745614147
15 |
16 | {}
--------------------------------------------------------------------------------
/ch7/synthetics/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-synthetics",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "react-scripts start",
7 | "build": "react-scripts build",
8 | "test": "sls package -r us-east-1 -s test",
9 | "dp:lcl": "sls deploy -v -r us-east-1",
10 | "rm:lcl": "sls remove -r us-east-1"
11 | },
12 | "dependencies": {
13 | "amazon-cognito-auth-js": "1.2.4",
14 | "react": "16.3.2",
15 | "react-dom": "16.3.2"
16 | },
17 | "devDependencies": {
18 | "react-scripts": "1.1.5",
19 | "react-router-dom": "4.3.1",
20 | "serverless": "1.26.0",
21 | "serverless-spa-config": "1.0.2",
22 | "serverless-spa-deploy": "1.0.0"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ch5/README.md:
--------------------------------------------------------------------------------
1 | # Securing Cloud-Native Systems
2 |
3 | 1. [Securing your cloud account](./account-as-code)
4 | 2. [Creating a federated identity pool](./cognito-pool)
5 | 3. [Implementing sign up, sign in and sign out](./cognito-signin)
6 | 4. [Securing an API gateway with OpenID Connect](./cognito-authorizer)
7 | 5. [Implementing a custom authorizer](./custom-authorizer)
8 | 6. [Authorizing a GraphQL based service](./graphql-jwt)
9 | 7. [Implementing a JWT filter](./jwt-filter)
10 | 8. [Using envelope encryption](./envelope-encryption)
11 | 9. [Creating an SSL certificate for encryption in transit](./ssl-cert)
12 | 10. [Configuring a web application firewall](./waf)
13 | 11. [Replicating the data lake for disaster recovery](./dr)
14 |
--------------------------------------------------------------------------------
/ch9/session-consistency/spa/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cncb-session-consistency-spa",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "react-scripts start",
7 | "build": "react-scripts build",
8 | "test": "sls package -r us-east-1 -s test",
9 | "dp:lcl": "sls deploy -v -r us-east-1",
10 | "rm:lcl": "sls remove -r us-east-1"
11 | },
12 | "dependencies": {
13 | "apollo-boost": "^0.1.12",
14 | "graphql": "^0.13.2",
15 | "react": "16.2.0",
16 | "react-apollo": "^2.1.9",
17 | "react-dom": "16.2.0"
18 | },
19 | "devDependencies": {
20 | "react-scripts": "1.1.1",
21 | "serverless": "1.26.0",
22 | "serverless-spa-deploy": "^1.0.0"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ch2/materialized-view-dynamodb/README.md:
--------------------------------------------------------------------------------
1 | # Creating a materialized view in DynamoDB
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch2/materialized-view-dynamodb --path cncb-materialized-view-dynamodb
5 | 2. cd cncb-materialized-view-dynamodb
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. publish an event from a separate terminal
10 | * cd ../cncb-event-stream
11 | * sls invoke -r us-east-1 -f publish -s $MY_STAGE -d '{"type":"thing-created"}'
12 | 7. sls logs -f listener -r us-east-1 -s $MY_STAGE
13 | 8. sls invoke -r us-east-1 -f query -s $MY_STAGE -d
14 | 9. npm run rm:lcl -- -s $MY_STAGE
15 |
--------------------------------------------------------------------------------
/ch3/esg-outbound/README.md:
--------------------------------------------------------------------------------
1 | # Implementing an outbound external service gateway
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch3/esg-outbound --path cncb-esg-outbound
5 | 2. cd cncb-esg-outbound
6 | 3. npm install
7 | 4. npm test -- -s $MY_STAGE
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. publish an event from a separate terminal
10 | * cd ../cncb-event-stream
11 | * sls invoke -r us-east-1 -f publish -s $MY_STAGE -d '{"type":"issue-created","issue":{"new":{"title":"issue one","description":"this is issue one.","id":"33333333-55555-1111-1111-111111111111"}}}'
12 | 7. sls logs -f listener -r us-east-1 -s $MY_STAGE
13 | 9. npm run rm:lcl -- -s $MY_STAGE
14 |
--------------------------------------------------------------------------------
/ch5/graphql-jwt/schema/thing/typedefs.js:
--------------------------------------------------------------------------------
1 | module.exports = `
2 | type Thing {
3 | id: String!
4 | name: String
5 | description: String
6 | }
7 |
8 | type ThingConnection {
9 | items: [Thing!]!
10 | cursor: String
11 | }
12 |
13 | extend type Query {
14 | thing(id: String!): Thing
15 | things(name: String, limit: Int, cursor: String): ThingConnection
16 | }
17 |
18 | input ThingInput {
19 | id: String
20 | name: String!
21 | description: String
22 | }
23 |
24 | extend type Mutation {
25 | saveThing(
26 | input: ThingInput
27 | ): Thing @hasRole(roles: ["Author"])
28 | deleteThing(
29 | id: ID!
30 | ): Thing @hasRole(roles: ["Manager"])
31 | }
32 | `;
33 |
--------------------------------------------------------------------------------
/ch6/transitive-testing/author-bff/fixtures/dynamodb.us-east-1.amazonaws.com-443/get-thing0:
--------------------------------------------------------------------------------
1 | POST /
2 | content-type: application/x-amz-json-1.0
3 | x-amz-target: DynamoDB_20120810.GetItem
4 | host: dynamodb.us-east-1.amazonaws.com
5 | body: {\"TableName\":\"stg-cncb-transitive-testing-author-bff-things\",\"Key\":{\"id\":{\"S\":\"00000000-0000-0000-0000-000000000000\"}}}
6 |
7 | HTTP/1.1 200 OK
8 | server: Server
9 | date: Sun, 17 Jun 2018 21:26:46 GMT
10 | content-type: application/x-amz-json-1.0
11 | content-length: 82
12 | connection: keep-alive
13 | x-amzn-requestid: AQRBJO9RV5EKDR4R7K0G9G92L7VV4KQNSO5AEMVJF66Q9ASUAAJG
14 | x-amz-crc32: 3235158845
15 |
16 | {"Item":{"id":{"S":"00000000-0000-0000-0000-000000000000"},"name":{"S":"thing0"}}}
17 |
--------------------------------------------------------------------------------
/ch3/esg-sqs-inbound/README.md:
--------------------------------------------------------------------------------
1 | # Implementing an inbound external service gateway from SQS
2 |
3 | This is a bonus recipe as Lambda SQS support was not available at the time the book outline was approved.
4 |
5 | ## How to do it...
6 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch3/esg-sqs-inbound --path cncb-esg-sqs-inbound
7 | 2. cd cncb-esg-sqs-inbound
8 | 3. npm install
9 | 4. npm test
10 | 5. npm run dp:lcl -- -s $MY_STAGE
11 | 6. sls invoke -r us-east-1 -f submit -s $MY_STAGE -d '{"id":"33333333-8888-0000-0000-111111111111","name":"thing eight"}'
12 | 7. sls logs -f submit -r us-east-1 -s $MY_STAGE
13 | 8. sls logs -f trigger -r us-east-1 -s $MY_STAGE
14 | 9. npm run rm:lcl -- -s $MY_STAGE
15 |
--------------------------------------------------------------------------------
/ch6/integration-testing/test/int/save/index.test.js:
--------------------------------------------------------------------------------
1 | import 'mocha';
2 | import { expect } from 'chai';
3 |
4 | const supertest = require('supertest');
5 |
6 | const endpoint = process.env.ENDPOINT ? process.env.ENDPOINT : 'http://localhost:3001';
7 | const client = supertest(endpoint);
8 |
9 | const THING = { name: 'thing0' };
10 |
11 | describe('save/index.js', () => {
12 | it('should save', () => client.post('/things')
13 | .send(THING)
14 | // .set('Authorization', JWT)
15 | .expect(201)
16 | .expect((res) => {
17 | // console.log('RES: %s', JSON.stringify(res, null, 2));
18 | expect(res.header.location).to.equal('https://localhost:3001/stg/things/00000000-0000-0000-0000-000000000000');
19 | }));
20 | });
21 |
--------------------------------------------------------------------------------
/ch6/contract-testing-sync/bff/test/int/save/index.test.js:
--------------------------------------------------------------------------------
1 | import 'mocha';
2 | import { expect } from 'chai';
3 |
4 | const supertest = require('supertest');
5 |
6 | const endpoint = process.env.ENDPOINT ? process.env.ENDPOINT : 'http://localhost:3001';
7 | const client = supertest(endpoint);
8 |
9 | const THING = { name: 'thing0' };
10 |
11 | describe('save/index.js', () => {
12 | it('should save', () => client.post('/things')
13 | .send(THING)
14 | // .set('Authorization', JWT)
15 | .expect(201)
16 | .expect((res) => {
17 | // console.log('RES: %s', JSON.stringify(res, null, 2));
18 | expect(res.header.location).to.equal('https://localhost:3001/stg/things/00000000-0000-0000-0000-000000000000');
19 | }));
20 | });
21 |
--------------------------------------------------------------------------------
/ch5/custom-authorizer/README.md:
--------------------------------------------------------------------------------
1 | # Implementing a custom authorizer
2 |
3 | ## How to do it...
4 | 1. sls create --template-url https://github.com/danteinc/js-cloud-native-cookbook/tree/master/ch5/custom-authorizer --path cncb-custom-authorizer
5 | 2. cd cncb-custom-authorizer
6 | 3. npm install
7 | 4. npm test
8 | 5. npm run dp:lcl -- -s $MY_STAGE
9 | 6. curl -v https://xyz.execute-api.us-east-1.amazonaws.com/$MY_STAGE/hello | json_pp
10 | 7. export CNCB_TOKEN=1234567890.1234567890
11 | 8. curl -v -H "Authorization: Bearer $CNCB_TOKEN" https://xyz.execute-api.us-east-1.amazonaws.com/$MY_STAGE/hello | json_pp
12 | 9. sls logs -f authorizer -r us-east-1 -s $MY_STAGE
13 | 10. sls logs -f hello -r us-east-1 -s $MY_STAGE
14 | 11. npm run rm:lcl -- -s $MY_STAGE
15 |
--------------------------------------------------------------------------------
/ch6/contract-testing-async/upstream/test/int/save/index.test.js:
--------------------------------------------------------------------------------
1 | import 'mocha';
2 | import { expect } from 'chai';
3 |
4 | const supertest = require('supertest');
5 |
6 | const endpoint = process.env.ENDPOINT ? process.env.ENDPOINT : 'http://localhost:3001';
7 | const client = supertest(endpoint);
8 |
9 | const THING = { name: 'thing0' };
10 |
11 | describe('save/index.js', () => {
12 | it('should save', () => client.post('/things')
13 | .send(THING)
14 | // .set('Authorization', JWT)
15 | .expect(201)
16 | .expect((res) => {
17 | // console.log('RES: %s', JSON.stringify(res, null, 2));
18 | expect(res.header.location).to.equal('https://localhost:3001/stg/things/00000000-0000-0000-0000-000000000000');
19 | }));
20 | });
21 |
--------------------------------------------------------------------------------