- Print
- DarkLight
CloudFront Deployment (NPM Package)
Instead of managing your AWS routes through Darwinium, Darwinium may also deploy to a static, route independent Node.JS package that may be installed through NPM.
Darwinium requires Top Level Await, which is currently only supported by ES Modules.
Attempting to call darwiniumInit() function in your request handler will not only be subject it to a more aggressive timeout, but will run also far slower because of nuances in AWS scheduling.
Add Darwinium Package to Your Lambda
Darwinium provides libraries that can be implemented as part of your lambda project. To access these, you will require an SDK token.
To access these libraries in the @darwinium
scope, you will need to append your ~/.npmrc
(or yarnrc if you are using yarn):
cat <<EOF >> ~/.npmrc
@darwinium:registry=https://packages.darwinium.com/artifactory/api/npm/dwn-npm
//packages.darwinium.com/artifactory/api/npm/:_auth=`echo -n '<your darwinium email>:<your SDK token>' | base64`
EOF
- Replace
<your darwinium email>
with your Darwinium email (eg foobar@example.com) - Replace
<your SDK token>
with your SDK Token
Then, add Darwinium's Cloudfront worker package to your OriginRequest lambda project by using npm install @darwinium.com/dwn_cloudfront_worker
or by manually appending it to your projects package.json
:
{
"dependencies": {
"@darwinium/dwn_cloudfront_worker": "^0.9.0"
}
}
Create a New Deployment Target
Create a new target using the + Add Target button inside Admin -> Nodes -> Settings -> Edge Deployment.
Select AWS Cloudfront (NPM) as the CDN vendor.
Initialize Darwinium
Darwinium will self-configure by loading its dynamic configuration on cold start. It requires top-level await, available in Node 18 and above (all runtimes below Node 18 have been deprecated by AWS as of June 2024).
The configuration loaded is stored within the CloudFront edge cache itself and is loaded direct to memory from a single stream to ensure cold start time is as fast as possible.
The exact parameters to darwiniumInit() are unique for each deployment target and may be copied from the Edge Deployment UI above.
import { darwiniumInit, darwiniumOriginRequestEventHandler } from "@darwinium/dwn_cloudfront_worker";
await darwiniumInit({
apiToken: "00000000-0000-0000-0000-000000000000",
instanceId: "00000000-0000-0000-0000-000000000000"
});
Call Request Handler Function
The darwiniumOriginRequestEventHandler
should be called at the very top of your OriginRequest lambda. It takes the same arguments of a standard CloudFrontRequestHandler and performs all functionality to protect this route.
export const handler: AWSLambda.CloudFrontRequestHandler = (
event: AWSLambda.CloudFrontRequestEvent,
context: AWSLambda.Context,
callback: AWSLambda.Callback<AWSLambda.CloudFrontRequestResult>,
) => {
if (darwiniumOriginRequestEventHandler(
event,
context,
(result: DarwiniumResultRequest | DarwiniumResultResponse | undefined) => {
callback(null, darwiniumRequestResponseToCloudFront(result, request));
})) {
// In this situation, Darwinium is performing a loopback and the worker should not run additional code.
return;
}
// Your existing Origin Request Functionality can run here, asynchronously to Darwinium or after it.
};
The Request Handler function returns a boolean value.
Returning true signifies that the Darwinium edge module requires access to the response and intends to loop-back into the CDN. It will asynchronously invoke the passed callback with the response it receives from re-invoking this route.
No further processing should be done inside this invocation of the request handler and callback should not be called within this invocation.
When this route is re-invoked, the origin-request lambda will be executed again immediately, allowing your own code to run immediately after and ensuring all logic is run exactly one.
Returning false signifies that the Darwinium edge module either does not require access to the response, or that it is running within the invocation of OriginResponse inside the loopback. In this situation, the callback passed in will not be invoked and the caller is responsible for invoking it.
API Reference
Function: darwiniumInit()
darwiniumInit(
initOption
):Promise
<void
>
Load Dynamic configuration from cloudflare edge cache.
This should be called once only and always from the top level scope, not within a callback.
Parameters
• initOption: InitOption
Initialization options taken from Darwinium's portal. This connects a worker to a set of dynamic configurations.
Returns
Function: darwiniumOriginRequestEventHandler()
darwiniumOriginRequestEventHandler(
event
,context
,callback
):boolean
Parameters
• event: CloudFrontRequestEvent
Event from Lambda at Edge event handler
• context: Context
Context from Lambda at Edge event handler
• callback: DarwiniumCallback
Asynchronous callback to return result.
Returns
boolean
True if Darwinium is performing a loopback, that is re-invoking the same path inline in order to examine the response body; in this situation, since this lambda will run again, it is best to not run other logic in this event handler. False in all other cases.
Function: darwiniumRequestResponseToCloudFront()
darwiniumRequestResponseToCloudFront(
result
,request
):CloudFrontResultResponse
|CloudFrontRequest
Parameters
• result: DarwiniumResultResponse|DarwiniumResultRequest
result from darwinium callback.
• request: CloudFrontRequest
request object from event handler
Returns
CloudFrontResultResponse
| CloudFrontRequest
request or response to be passed to event callback or returned from async event handler function.
Function: applyDarwiniumRequestToCloudFront()
applyDarwiniumRequestToCloudFront(
dwnRequest
,cfRequest
):CloudFrontRequest
Parameters
• dwnRequest: DarwiniumResultRequest
request results from Darwinium to be applied
• cfRequest: CloudFrontRequest
request object from event handler to be modified
Returns
CloudFrontRequest
request to be passed to event callback or returned from async event handler function.
Function: darwiniumResponseToCloudFront()
darwiniumResponseToCloudFront(
dwnResponse
):CloudFrontResultResponse
Parameters
• dwnResponse: DarwiniumResultResponse
response received inside Darwinium Callback
Returns
CloudFrontResultResponse
response to be passed to event callback or returned from async event handler function.
Function: applyModifiedHeaders()
applyModifiedHeaders(
dwnHeaders
,cfHeaders
):CloudFrontHeaders
Parameters
• dwnHeaders: DarwiniumModifiedHeader
[]
Instructions to modify header
• cfHeaders: CloudFrontHeaders
Original headers from cloudfront handler, will be modified according to dwnHeaders
Returns
CloudFrontHeaders
modified headers
Function: applySetCookies()
applySetCookies(
dwnCookies
,cfHeaders
):CloudFrontHeaders
Parameters
• dwnCookies: DarwiniumSetCookie
[]
Instructions to add cookies
• cfHeaders: CloudFrontHeaders
Original headers from cloudfront handler, will be modified according to dwnCookies
Returns
CloudFrontHeaders
modified headers
Type Alias: DarwiniumCallback()
DarwiniumCallback: (
result
) =>void
Callback to be passed to darwiniumOriginRequestEventHandler
This may return either a DarwiniumResultRequest (continue to origin)
alternatively it may return a DarwiniumResultResponse which is a direct respose to the caller without calling origin.
Parameters
• result: DarwiniumResultRequest
| DarwiniumResultResponse
| undefined
Returns
void
Type Alias: InitOption
InitOption:
object
Initialization options taken from Darwinium's portal. This connects a worker to a set of dynamic configurations.
Type declaration
apiToken
apiToken:
string
Api token from portal
instanceId
instanceId:
string
Instance ID from portal
Type Alias: DarwiniumBody
DarwiniumBody:
object
Instructions to send or overwrite a body for request or response
Type declaration
data
data:
string
Data to return
encoding
encoding:
"base64"
|"text"
Encoding of data (for setting CloudFrontRequest.body.encoding
and CloudFrontResultResponse.bodyEncoding
) )
Type Alias: DarwiniumModifiedHeader
DarwiniumModifiedHeader:
object
Instructions for modifying headers in a request or a response
When fields are populated, please refer to this table to see what sort of an operation it is:
oldValue newValue operation
string null deletion
null string adding
string string modification
name
name:
string
The name of a header to modify.
This may be mixed case. Please be sure to lowercase it before looking into aws-lambda#CloudFrontHeaders.
newValue
newValue:
string
|null
When not null, this signifies to add or modify a header to this value
oldValue
oldValue:
string
|null
When not null, this signifies to remove or replace a header with this existing value
Type Alias: DarwiniumResultRequest
DarwiniumResultRequest:
object
Instructions to modify request that is forwarded to origin
Type declaration
requestBody?
optional
requestBody:DarwiniumBody
Instructions to overwrite request body if applicable
requestHeaders?
optional
requestHeaders:DarwiniumModifiedHeader
[]
Instructions to modify headers of request if applicable
requestQuerystring?
optional
requestQuerystring:string
The query string to modify aws-lambda#CloudFrontRequest.querystring to.
requestUri?
optional
requestUri:string
The URI to modify CloudFrontRequest.uri
to.
Type Alias: DarwiniumResultResponse
DarwiniumResultResponse:
object
Instructions to directly return a result from lambda without forwarding to origin OR the results of a "loopback" operation.
response?
optional
response:DarwiniumResponse
Instructions to overwrite response body if applicable
responseCookies?
optional
responseCookies:DarwiniumSetCookie
[]
Instructions to set new cookies if applicable
responseHeaders?
optional
responseHeaders:DarwiniumModifiedHeader
[]
Instructions to modify headers of response if applicable
Type Alias: DarwiniumResponseStatus
DarwiniumResponseStatus:
object
Instructions to set status when directly responding.
Type declaration
code
code:
number
Numeric HTTP status code to return (e.g. )
This is intended to use in CloudFrontResultResponse.status
Example
404
description
description:
string
Human readable HTTP status to return
This is intended to use in CloudFrontResultResponse.statusDescription
Example
"File Not Found"
Type Alias: DarwiniumSetCookie
DarwiniumSetCookie:
object
Instructions to add a cookie to request or response.
Example
let for_this_header = "Set-Cookie: dwn-journey=30043ada-c03e-421e-988a-50ed41e14617; Domain=example.com; Secure; HttpOnly";
let this_will_be_returned: DarwiniumSetCookie = {
name: "dwn-journey",
value: "3043ada-c03e-421e-988a-50ed41e14617",
attributes: "Domain=example.com; Secure; HttpOnly"
}
Type declaration
attributes?
optional
attributes:string
Attributes to send on set-cookie
Example
"Domain=example.com; Secure; HttpOnly"
name
name:
string
Name of cookie to set
Example
"dwn-journey"
value
value:
string
Value of cookie to set
Example
"30043ada-c03e-421e-988a-50ed41e14617"