Giter Site home page Giter Site logo

sid88in / serverless-appsync-plugin Goto Github PK

View Code? Open in Web Editor NEW
948.0 948.0 183.0 3.07 MB

serverless plugin for appsync

License: MIT License

JavaScript 0.18% TypeScript 99.82%
aws-appsync dynamodb elasticsearch graphql lambda serverless-applications serverless-framework serverless-plugin

serverless-appsync-plugin's People

Contributors

aleksac avatar anastyn avatar antonshevel avatar asnaseer-resilient avatar bboure avatar c10h22 avatar deadcoder0904 avatar deankostomaj avatar ebisbe avatar erezrokah avatar francisu avatar hardchor avatar josephnle avatar jpstrikesback avatar kinyat avatar lulzneko avatar maddijoyce avatar mfogel avatar mihaerzen avatar nikgraf avatar pmuens avatar roznalex avatar sebflipper avatar shmygol avatar sid88in avatar tastefulelk avatar thomasmichaelwallace avatar toxuin avatar vlesierse avatar zy-ang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

serverless-appsync-plugin's Issues

serverless update-appsync does not recognize changes to userPoolId

Hi. Maybe someone can confirm this. I have a serverless-appsync project using cognito for auth and I changed userPoolId in the serverless.yml. After I ran update-appsync no change is registered in appSync. I had to go into the AWS AppSync web console and make the changes manually.

authenticationType: AMAZON_COGNITO_USER_POOLS
userPoolConfig: #for use with COGNITO
awsRegion: us-west-2 # required # region
defaultAction: ALLOW
userPoolId: us-west-2_iswCEJijj ##<-- changes here not reflected on update-appsync

Actually I found this out because I was just using API key for auth. When I changed the auth type from API key to Cognito the value I put for userPoolId was completely wrong (I think I had a cognito ARN in there) and update-appsync did not complain. No errors or warning given.

accountId in serverless.yml can be any integer

I noticed accountId cannot be missing but as long as it present it can be any number and the deploy goes through successfully. This is a bit confusing because serverless uses the aws profile credentials to figure out which account to deploy to and this accountId in this plugin has no affect. Am I missing something here?

Error deploying in CodeBuild

Deployment works in my command line but in AWS CodeBuild (image aws/codebuild/nodejs:6.3.1) it breaks. Deployment in CodeBuild works fine on serverless-appsync-plugin 0.0.6 but breaks on serverless-appsync-plugin 0.0.7.

Taking a wild guess, to me it seems probable that the old node version used in CodeBuild causes this error. I find that CodeBuild should be supported and therefore the latest node version available in CodeBuild (6.3.1) should be supported.

"serverless deploy" command breaks:

[Container] 2018/04/12 07:38:52 Running command serverless deploy -v --stage ${BUILD_LEVEL}

Serverless Error ---------------------------------------

Serverless plugin "serverless-appsync-plugin" initialization errored: Unexpected token )

"serverless update-appsync" command breaks:

[Container] 2018/04/12 07:46:06 Running command serverless update-appsync --stage ${BUILD_LEVEL}

Serverless Error ---------------------------------------

Serverless plugin "serverless-appsync-plugin" initialization errored: Unexpected token )

Merge deploy-appsync and update-appsync

I was thinking that maybe the deploy and update commands should be only one.
The plugin should be able to get the apiId from the existing (if any) appsync api.

What do you think?

More Verbose Errors

When I try to deploy I get the following error...

Serverless Error ---------------------------------------
Request mapping template not specified.

Since I am adapting this from the example I had tried to go through and comment out all the graphql queries/mutations/subscriptions that don't have a mapping template specified but I still get this error. It would be very helpful if the error would reference what in the graphql schema was lacking a mapping template.

Also, might it be better if unspecified mapping templates give a warning and not an error?

Support authenticationType: API_KEY

I'm attempting to use API_KEY authentication and I can't work out the correct format.
Looking at the code it would seem that a userPoolConfig is always required.

appSync:
    authenticationType: API_KEY
.request("AppSync", "updateGraphqlApi", {
        apiId: resolvedConfig.apiId,
        authenticationType: resolvedConfig.authenticationType,
        name: resolvedConfig.name,
        userPoolConfig: {
          awsRegion: resolvedConfig.region,
          defaultAction: resolvedConfig.userPoolConfig.defaultAction, // userPoolConfig is null NPE
          userPoolId: resolvedConfig.userPoolConfig.userPoolId
    }
})

Add Data Sources

The plugin should add data sources as specified in the custom.appSync.dataSources key in serverless.yml.

I'm proposing to slightly change the config dataSources structure to:

    dataSources:
      - type: AMAZON_DYNAMODB
        name: Users
        description: 'Users table'
        config:
           tableName: 'Users'
           # useCallerCredentials: true # optional, applies to cognito callers
      - type: AMAZON_ELASTICSEARCH
        name: TweetSearch
        description: 'Tweet ES'
        config:
           endpoint: 'Tweets'
      - type: AWS_LAMBDA
        name: UserAvatar
        description: 'User Avatar'
        config:
           lambdaFunctionArn: 'arn:aws:lambda:${REGION}:${ACCOUNT_ID}:function:appsync-lambda-example'

review existing code

  • review appsync client integration code in serverless graphQL and add amplify integration (make sure all functionalities of appsync react client are included).

  • review existing appsync deploy code to make sure there are no errors. Can we read schema / mapping templates from text file instead of creating js objects?

pagination of tweets

  • mapping template for pagination of tweets in dynamodb example. This one is tricky because our item is a json blob. For now, each user has a tweet json blob associated with him/her. We simply parse the json and show it to users, but if we want to paginate through the items, do we need to create secondary indexes? not sure because in my understanding pagination can only happen in primary key.

Initial feature draft

On ‘serverless deploy’ it creates or updates the appsync schema. I suggest by default it uses the file ‘schema.graphql’ located in the root of the project.

Optionally the location of the schema file can be changed with a parameter nested in the custom section in serverless.yml. A possible name could be ‘graphqlSchema’

The API calls should happen after the new resources and functions are deployed so they can be referenced and it doesn’t happen that a schema goes live that doesn’t have the necessary resources up & running.

On ‘serverless remove’ the appsync schema is removed as well. Here it happens before the cloudformation stack is removed.

Note: I don’t know to much about the mappings yet. Will read up on them and we can extend/update/correct this initial draft.

combine mapping templates

Enhancement: The idea would be to optionally have just a single mapping template file for a given query/mutation. Ofter the response template is just a single line forwarding the response value anyways. Cuts down on clutter in the file tree.

mutation - add single tweet

  • mapping template to add a new tweet. For now, in our mutation its easy to add array of tweets but what if we just want to append 1 tweet. In this case naive solution is to getItem on user tweets and add a new tweet and putitem .. or maybe use updateitem? not sure.

Make `apiKey` optional for update-appsync

Could you make apiKey config param optional? I found that most of the time I run update-appsync to change only schema and/or mapping templates, and having to provide a valid API key for each update complicates the task, especially when you have few APIs and keys are rotated often.

Remove Promise Warning Messages From Output

Technically nothing is wrong but we need to return the callback this warning:

(node:38968) Warning: a promise was created in a handler at /Users/me/Desktop/repo/app/node_modules/serverless-appsync-plugin/index.js:403:15 but was not returned from it, see http://goo.gl/rRqMUw at new Promise (/Users/me/Desktop/repo/app/node_modules/bluebird/js/release/promise.js:79:10)

#58

Separate process.env yaml?

It seems like some things (like accountId) should be separated into it's a yml (or json) file that gets mapped to porcess.env. Many serious projects will need to take advantage of process.env at some point. Is there a best way to do this for aws lambdas?

Unable to get userPoolId from Ref

Currently under userPoolConfig.userPoolId a person must enter a string for the userPool. This is great if your developing just a single AppSync system without stages. However, if using stages, you may have different user pools.

It would be great if the plugin could use

userPoolConfig:
  userPoolId:
    Ref: UserPool

to pull the user pool id from the resources.

Discussion/Proposal for update/delete functionality with serverless-appsync-plugin

Wanted to create a little discussion here for anyone interested.. to talk about a proposal for how the update/delete functionality might work in the future.

Atm there is a cleanupDataSources function that makes an api call to AWS to find out what data sources you have on your API and compares it to the data sources you have set in your serverless.yml file. With that information it can determine what data sources aren't being used anymore and delete them. (But this could get a little bit tricky when a config grows to a large number of data sources/resolvers)

My proposal would be to; instead of making http requests to find out the data sources/resolvers needed to delete.. create a snapshot of the serverless.yml file.. and save it in a folder or something named snapshots or w/e.

With that snapshot; all you would need to do is compare locally.. that file and also your new config file that you are changing. It would determine the changes.. and make the necessary deletes to your API.

Hope we can get a few other people to weigh in on this.. and maybe share their ideas :)

Note: Snapshot files would also be good for doing rollbacks to a certain date.. or the last saved config.. or something like that as well. Maybe snapshots can have dates appended to the file names .. so u can rollback to a certain date, etc.

If anyone wants to check out the rough example I came up with on my fork you are more then welcome :) https://github.com/lolcoolkat/serverless-appsync-plugin/blob/master/index.js

I replaced the updateDataSources with a more general function (maybe should be split into multiple functions later) that cleans up the data sources/resolvers you aren't using, and also creates a snapshot at the end.. for future updates!

Multi stage AppSync API's

Is there a workaround to maintain multi stage setup (dev, beta, prod). apiId is necessary for provisioning, but how do we get about providing an input with multiple apiId depending on stage? Is an environment file the best option?

sls update-appsync ends up in error: "Missing required key 'id' in params"

sls deploy-appsync runs ok.

However, sls update-appsync ends up as below:

Serverless: Updating GraphQL Endpoint...
Serverless: GraphQL API ID: xxxxxxxxxx
Serverless: GraphQL Endpoint: https://xxxxxxx.appsync-api.us-east-1.amazonaws.com/graphql
Serverless: Updating API Key...
 
  Serverless Error ---------------------------------------
 
  Missing required key 'id' in params
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Forums:        forum.serverless.com
     Chat:          gitter.im/serverless/serverless
 
  Your Environment Information -----------------------------
     OS:                     darwin
     Node Version:           8.9.4
     Serverless Version:     1.26.1

EDIT:

Forgot to mention earlier, I do have the apiId set in serverless.yml

custom:
  appSync:
    apiId: xxxx

Just to confirm below is where I get the apiId from:
screen shot 2018-03-28 at 2 27 13 pm

Looking for contributors!

  • working with GraphQL?
  • have good ideas on how to extend this plugin?
  • love working with opensource?

Please reach out to me :)
Thanks
Sid

lambda function not created

I am trying to create a AppSync stack that uses just lambda functions instead of DynamoDB.
Running deploy-appsync creates the project. Every thing in this AppSync console looks good. But when I click on link to the lamba function in AWS AppSync > myApi > Data Sources it flashes an error (flashes it so quickly I cannot read it) before redirecting me to my list of lambda functions where it appears that the lambda function has not been created. When I check in the AWS CloudFormation console it also appear there is no evidence of any resources there either.

grab

(image shows a link to the lambda function but there is no function there when I hit the link. Seems it wasn't created.)

Here is my serverless.yml. It is a modified version of the example. I am thinking there is something missing from the resources section?

provider:
  name: aws
  runtime: nodejs6.10
  region: us-west-2  
functions:
  hello:
    handler: handler.hello
plugins:
   - serverless-appsync-plugin
custom:
  accountId: [redacted] # found here https://console.aws.amazon.com/billing/home?#/account
  appSync:
    name:  serverlessAPI # defaults to api
    authenticationType: AMAZON_COGNITO_USER_POOLS
    userPoolConfig:
      awsRegion: us-west-2  # required # region
      defaultAction: ALLOW
      userPoolId: us-west-2_SHawmnz0D # required # user pool ID
      region: us-west-2 # defaults to provider region
    mappingTemplatesLocation: mapping-templates # defaults to mapping-templates
    mappingTemplates:
      - dataSource: Serverless_Lambda_DS # data source name
        type: Query # Query, Mutation, Subscription
        field: getUserInfo
        request: getUserInfo-request-mapping-template.txt # request mapping template name
        response: getUserInfo-response-mapping-template.txt # response mapping template name
    schema: schema.graphql # defaults schema.graphql
    serviceRole: "AppSyncServiceRole"
    dataSources:
      - type: AWS_LAMBDA
        name: Serverless_Lambda_DS  # data source name
        description: 'Lambda DataSource'
        config:
          lambdaFunctionArn: "arn:aws:lambda:us-west-2:${self:custom.accountId}:function:serverless-lambda-dev-graphql"
          serviceRoleArn: "arn:aws:iam::${self:custom.accountId}:role/Lambda-${self:custom.appSync.serviceRole}"
resources:
  Resources:
    AppSyncLambdaServiceRole:
      Type: "AWS::IAM::Role"
      Properties:
        RoleName: "Lambda-${self:custom.appSync.serviceRole}"
        AssumeRolePolicyDocument:
          Version: "2012-10-17"
          Statement:
            -
              Effect: "Allow"
              Principal:
                Service:
                  - "appsync.amazonaws.com"
              Action:
                - "sts:AssumeRole"
        Policies:
          -
            PolicyName: "Lambda-${self:custom.appSync.serviceRole}-Policy"
            PolicyDocument:
              Version: "2012-10-17"
              Statement:
                -
                  Effect: "Allow"
                  Action:
                    - "lambda:invokeFunction"
                  Resource:
                    - "arn:aws:lambda:us-west-2:${self:custom.accountId}:function:serverless-lambda-dev-graphql"
                    - "arn:aws:lambda:us-west-2:${self:custom.accountId}:function:serverless-lambda-dev-graphql:*"```

Resolver Mappings

Just a quick note to say I'm going to be working on making the resolver mappings a bit more generalized.

Am I right to think that the serverless.yml should drive the resolver mappings? i.e.:

  • look for resolver mappings via the mappingTemplates key:
mappingTemplates:
  - dataSource: Tweets
    type: User
    field: topTweet
    request: "topTweet-request-mapping-template.txt"
    response: "topTweet-response-mapping-template.txt"
  - dataSource: Users
    type: Query
    field: meInfo
    request: "meInfo-request-mapping-template.txt"
    response: "meInfo-response-mapping-template.txt"
...
  • createResolver for each discovered mapping

Invalid Endpoint Configuration

I'm encountering an "Invalid endpoint configuration" error when I attempt to deploy a new AppSync API with an ElasticSearch domain as my data source.

The ES domain is on the same AWS account, has been created, and is ready for use. The custom part of my serverless.yml file is below, and the endpoint parameter was copy/pasted into it.

custom:
  accountId: [REDACTED]
  appSync:
    name: [REDACTED]
    authenticationType: API_KEY
    serviceRole: "AppSyncServiceRole"
    region: [REDACTED]
    schema: schema.graphql
    dataSources:
      - type: AMAZON_ELASTICSEARCH
        name: [REDACTED]
        config:
          endpoint: https://vpc-[REDACTED]-[REDACTED].[REDACTED].es.amazonaws.com
          serviceRoleArn: "???"

I have tried several different serviceRoleArns but nothing seems to make a difference.

What am I doing wrong? I'm pulling my hair out here.

service role to data source mapping

const serviceRoleElastic = arn:aws:iam::${accountId}:role/${roleNameElastic}; // Service IAM Role for appsync to access data sources
const serviceRoleDynamo = arn:aws:iam::${accountId}:role/${roleNameDynamo}; // Service IAM Role for appsync to access data sources

you may have 2 or more service roles and each data source is associated with 1 role:

const datasourceParams = [
  {
    apiId: appId /* required */,
    name: 'elastic' /* required */,
    type: 'AMAZON_ELASTICSEARCH' /* required */,
    description: 'my first data source',
    elasticsearchConfig: {
      awsRegion: awsRegion /* required */,
      endpoint: esEndpoint /* required */,
    },
    serviceRoleArn: serviceRoleElastic,
  },
  {
    apiId: appId /* required */,
    name: 'Users' /* required */,
    type: 'AMAZON_DYNAMODB' /* required */,
    description: 'Store user info',
    dynamodbConfig: {
      awsRegion: awsRegion /* required */,
      tableName: 'ESUsers' /* required */,
    },
    serviceRoleArn: serviceRoleDynamo,
  },
];

taking example below from readme of appsync plugin:

serviceRole: # required - example: "arn:aws:iam::${self:custom.accountId}:role/EXAMPLE-Role"
dataSources:
  - type: AMAZON_DYNAMODB
    name: Users
    description: 'Users table'
    config:
       tableName: 'Users'

update-appsync with Lambda Resolver

First, thank you for developing this great plugin. I have been setting up Appsync over the last week and it is awesome to use, given there is a good bit of trial/error, due to limited Appsync documentation.

I have run into a bug, possibly due to recent changes to Appsync. When you run the sls update-appsync and you have a "Lambda Data Source" (for a Lambda based resolver), it drops the role after each update. Deploy seem to work. So every time I run update-appsync, I have to go click the dropdown in datasource and set the Region, Function Arn, and role to make every work. The update throws no errors, and was a pain to chase down when my query just stopped working.

Right after an update (before I set the ARNs/Role) the Lambda Resolver returns: java.lang.IllegalArgumentException: Illegal ARN format detected, the relative-id must follow the format function::

-Michael

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.