@aljendro/serverless-appsync-simulator

    0.13.1 • Public • Published

    semantic-release Release All Contributors

    This serverless plugin is a wrapper for amplify-appsync-simulator made for testing AppSync APIs built with serverless-appsync-plugin.

    Requires

    Install

    npm install serverless-appsync-simulator
    # or
    yarn add serverless-appsync-simulator

    Usage

    This plugin relies on your serverless yml file and on the serverless-offline plugin.

    plugins:
      - serverless-dynamodb-local # only if you need dynamodb resolvers and you don't have an external dynamodb
      - serverless-appsync-simulator
      - serverless-offline

    Note: Order is important serverless-appsync-simulator must go before serverless-offline

    To start the simulator, run the following command:

    sls offline start

    You should see in the logs something like:

    ...
    Serverless: AppSync endpoint: http://localhost:20002/graphql
    Serverless: GraphiQl: http://localhost:20002
    ...

    Configuration

    Put options under custom.appsync-simulator in your serverless.yml file

    option default description
    apiKey 0123456789 When using API_KEY as authentication type, the key to authenticate to the endpoint.
    port 20002 AppSync operations port
    wsPort 20003 AppSync subscriptions port
    location . (base directory) Location of the lambda functions handlers.
    lambda.loadLocalEnv false If true, all environment variables ($ env) will be accessible from the resolver function. Read more in section Environment variables.
    refMap {} A mapping of resource resolutions for the Ref function
    getAttMap {} A mapping of resource resolutions for the GetAtt function
    importValueMap {} A mapping of resource resolutions for the ImportValue function
    functions {} A mapping of external functions for providing invoke url for external fucntions
    dynamoDb.endpoint http://localhost:8000 Dynamodb endpoint. Specify it if you're not using serverless-dynamodb-local. Otherwise, port is taken from dynamodb-local conf
    dynamoDb.region localhost Dynamodb region. Specify it if you're connecting to a remote Dynamodb intance.
    dynamoDb.accessKeyId DEFAULT_ACCESS_KEY AWS Access Key ID to access DynamoDB
    dynamoDb.secretAccessKey DEFAULT_SECRET AWS Secret Key to access DynamoDB
    dynamoDb.sessionToken DEFAULT_ACCESS_TOKEEN AWS Session Token to access DynamoDB, only if you have temporary security credentials configured on AWS
    dynamoDb.* You can add every configuration accepted by DynamoDB SDK
    watch - *.graphql
    - *.vtl
    Array of glob patterns to watch for hot-reloading.

    Example:

    custom:
      appsync-simulator:
        location: '.webpack/service' # use webpack build directory
        dynamoDb:
          endpoint: 'http://my-custom-dynamo:8000'

    Hot-reloading

    By default, the simulator will hot-relad when changes to *.graphql or *.vtl files are detected. Changes to *.yml files are not supported (yet? - this is a Serverless Framework limitation). You will need to restart the simulator each time you change yml files.

    Hot-reloading relies on watchman. Make sure it is installed on your system.

    You can change the files being watched with the watch option. Or you can opt-out by leaving an emptry array or set the option to false.

    Note: Functions should not require hot-reloading, unless you are using a transpiler or a bundler (such as webpack, babel or typescript), un which case you should delegate hot-reloading to that instead.

    Resource CloudFormation functions resolution

    This plugin supports some resources resolution from the Ref, Fn::GetAtt and Fn::ImportValue functions in your yaml file. It also supports some other Cfn functions such as Fn::Join, Fb::Sub, etc.

    Note: Under the hood, this features relies on the cfn-resolver-lib package. For more info on supported cfn functions, refer to the documentation

    Basic usage

    You can reference resources in your functions' environment variables (that will be accessible from your lambda functions) or datasource definitions. The plugin will automatically resolve them for you.

    provider:
      environment:
        BUCKET_NAME:
          Ref: MyBucket # resolves to `my-bucket-name`
    
    resources:
      Resources:
        MyDbTable:
          Type: AWS::DynamoDB::Table
          Properties:
            TableName: myTable
          ...
        MyBucket:
          Type: AWS::S3::Bucket
          Properties:
            BucketName: my-bucket-name
        ...
    
    # in your appsync config
    dataSources:
      - type: AMAZON_DYNAMODB
        name: dynamosource
        config:
          tableName:
            Ref: MyDbTable # resolves to `myTable`

    Override (or mock) values

    Sometimes, some references cannot be resolved, as they come from an Output from Cloudformation; or you might want to use mocked values in your local environment.

    In those cases, you can define (or override) those values using the refMap, getAttMap and importValueMap options.

    • refMap takes a mapping of resource name to value pairs
    • getAttMap takes a mapping of resource name to attribute/values pairs
    • importValueMap takes a mapping of import name to values pairs

    Example:

    custom:
      appsync-simulator:
        refMap:
          # Override `MyDbTable` resolution from the previous example.
          MyDbTable: 'mock-myTable'
        getAttMap:
          # define ElasticSearchInstance DomainName
          ElasticSearchInstance:
            DomainEndpoint: 'localhost:9200'
        importValueMap:
          other-service-api-url: 'https://other.api.url.com/graphql'
    
    # in your appsync config
    dataSources:
      - type: AMAZON_ELASTICSEARCH
        name: elasticsource
        config:
          # endpoint resolves as 'http://localhost:9200'
          endpoint:
            Fn::Join:
              - ''
              - - https://
                - Fn::GetAtt:
                    - ElasticSearchInstance
                    - DomainEndpoint

    Key-value mock notation

    In some special cases you will need to use key-value mock nottation. Good example can be case when you need to include serverless stage value (${self:provider.stage}) in the import name.

    This notation can be used with all mocks - refMap, getAttMap and importValueMap

    provider:
      environment:
        FINISH_ACTIVITY_FUNCTION_ARN:
          Fn::ImportValue: other-service-api-${self:provider.stage}-url
    
    custom:
      serverless-appsync-simulator:
        importValueMap:
          - key: other-service-api-${self:provider.stage}-url
            value: 'https://other.api.url.com/graphql'

    Environment variables

    custom:
      appsync-simulator:
        lambda:
          loadLocalEnv: true

    If true, all environment variables ($ env) will be accessible from the resolver function.

    If false, only environment variables defined in serverless.yml will be accessible from the resolver function.

    Note: serverless.yml environment variables have higher priority than local environment variables. Thus some of your local environment variables, could get overridden by environment variables from serverless.yml.

    Limitations

    This plugin only tries to resolve the following parts of the yml tree:

    • provider.environment
    • functions[*].environment
    • custom.appSync

    If you have the need of resolving others, feel free to open an issue and explain your use case.

    For now, the supported resources to be automatically resovled by Ref: are:

    • DynamoDb tables
    • S3 Buckets

    Feel free to open a PR or an issue to extend them as well.

    External functions

    When a function is not defined withing the current serverless file you can still call it by providing an invoke url which should point to a REST method. Make sure you specify "get" or "post" for the method. Default is "get", but you probably want "post".

    custom:
      appsync-simulator:
        functions:
          addUser:
            url: http://localhost:3016/2015-03-31/functions/addUser/invocations
            method: post
          addPost:
            url: https://jsonplaceholder.typicode.com/posts
            method: post

    Supported Resolver types

    This plugin supports resolvers implemented by amplify-appsync-simulator, as well as custom resolvers.

    From Aws Amplify:

    • NONE
    • AWS_LAMBDA
    • AMAZON_DYNAMODB
    • PIPELINE

    Implemented by this plugin

    • AMAZON_ELASTIC_SEARCH
    • HTTP

    Not Supported / TODO

    • RELATIONAL_DATABASE

    Contributors

    Thanks goes to these wonderful people (emoji key):


    Benoît Bouré

    💻

    Filip Pýrek

    💻

    Marco Reni

    💻

    Egor Dmitriev

    💻

    Steffen Schwark

    💻

    Nicky Moelholm

    💻

    g-awa

    💻

    Lee Mulvey

    💻

    Jimmy Hurrah

    💻

    Abdala

    🤔

    Alexandru Savin

    📖

    Scale93

    💻 📖

    This project follows the all-contributors specification. Contributions of any kind welcome!

    Install

    npm i @aljendro/serverless-appsync-simulator

    DownloadsWeekly Downloads

    41

    Version

    0.13.1

    License

    MIT

    Unpacked Size

    37.4 kB

    Total Files

    11

    Last publish

    Collaborators

    • aljendro