Skip to content

Pass origin path in REST scenario #364

@jaulz

Description

@jaulz

Start from the Use-case

Unfortunately, I still need to use the REST protocol of the API Gateway (because v2 is not available in Switzerland) but that means that there is an ugly stage prefix in the URL (even with a custom domain). It would be nice if we could pass the origin path to the default origin of the CloudFront distribution so we can hide the stage prefix from end users.

Example Config

service: ${env:APP_ID}

frameworkVersion: '3'

configValidationMode: error

custom:
  rootDomain: example.org
  appName: Test
  appId: ${self:service}
  domain: ${self:custom.appId}.${self:custom.rootDomain}

plugins:
    - ./vendor/bref/bref
    - serverless-lift

provider:
    name: aws
    region: eu-central-2
    stage: production
    memorySize: 1024

package:
    # Files and directories to include/exclude from deployment
    patterns:
        - '!.husky/**'
        - '!.vscode/**'
        - '!.yarn/**'
        - '!node_modules/**'
        - '!public/storage'
        - '!resources/assets/**'
        - '!storage/**'
        - '!tests/**'

functions:
    # This function runs the Laravel website/API
    web:
        handler: public/index.php
        runtime: php-81-fpm
        timeout: 28 # in seconds (API Gateway has a timeout of 29 seconds)
        events:
            - http: 'ANY /'
            - http: 'ANY /{proxy+}'

constructs:
    app:
        type: server-side-website
        domain: ${self:custom.domain}
        certificate: ...
        # Either "rest" (v1) or "http" (v2, the default) but right now only v1 is available in Switzerland
        apiGateway: 'rest'
        assets:
            '/build/*': public/build
            '/css/*': public/css
            '/fonts/*': public/fonts
            '/js/*': public/js
            '/favicon.ico': public/favicon.ico
            '/robots.txt': public/robots.txt

resources:
    Resources:
        Storage:
            Type: AWS::S3::Bucket
        CacheTable:
            Type: AWS::DynamoDB::Table
            Properties:
                AttributeDefinitions: # only keys are defined here, other attributes are dynamic
                    -   AttributeName: id # adds a mandatory id field
                        AttributeType: S # the type of id is a string
                BillingMode: PAY_PER_REQUEST # billed for each request instead of paying for a constant capacity
                TimeToLiveSpecification: # deletes cache keys automatically based on a ttl field which contains a timestamp
                    AttributeName: ttl
                    Enabled: true
                KeySchema:
                    -   AttributeName: id
                        KeyType: HASH # the type of key, HASH means partition key (similar to primary keys in SQL)
        Route53Record:
            Type: AWS::Route53::RecordSet
            Properties:
                HostedZoneId: ...
                Name: ${self:custom.domain}
                Type: A
                AliasTarget:
                    HostedZoneId: Z2FDTNDATAQYW2 # Cloudfront Route53 HostedZoneId. This does not change.
                    DNSName: ${construct:app.cname}

Implementation Idea

As far as I could see we simply need to pass the name of the stage to the default origin (e.g. originPath: '/production',):

origin: new HttpOrigin(apiGatewayDomain, {
// API Gateway only supports HTTPS
protocolPolicy: OriginProtocolPolicy.HTTPS_ONLY,
}),

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions