serverless-appsync-plugin icon indicating copy to clipboard operation
serverless-appsync-plugin copied to clipboard

combine mapping templates

Open honkskillet opened this issue 6 years ago • 6 comments

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.

honkskillet avatar Apr 11 '18 12:04 honkskillet

Can you please explain with an example!

sid88in avatar Apr 11 '18 15:04 sid88in

Sure, say for a query addPost, i currently have two files

{ ## addPost-request-mapping-template.txt
    "version" : "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "addPost",
        "arguments":  $util.toJson($context.arguments)
    }
}

and

 ## addPost-response-mapping-template.txt
util.toJson($context.result)

All the response mapping templates in my project look like this. They just pass the rsults straight through. It would be better if I could have...

## addPost-mapping-templates.txt
{ request:{ 
    "version" : "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "addPost",
        "arguments":  $util.toJson($context.arguments)
    }
},
reponse:  util.toJson($context.result)
}

or something similar

honkskillet avatar Apr 11 '18 16:04 honkskillet

It seems that request/response fields are restricted to be a file path to be read. Have tried a file reference variable but it didn't work. For example:

mappingTemplates:
      # Customer
      - dataSource: Dynamo_customer
        type: Mutation 
        field: createCustomer
        request: ${file(customer-templates.vtl):create}
        response: ${file(customer-templates.vtl):response}
      - dataSource: Dynamo_customer 
        type: Mutation 
        field: deleteCustomer
        request: ${file(customer-templates.vtl):delete}
        response: ${file(customer-templates.vtl):response}

lucallero avatar Jan 13 '19 03:01 lucallero

@honkskillet I see you are using Lambda (at least in this example). I just have another approach for that. Basically I just have 2 Lambda templates: one for requests and one for responses. Since all lambdas use the same templates, I just reuse the same one for all resolvers.

I see you have "field": "addPost" in your request template. Not sure why you need it? Usually, the called lambda function should already give you that info, unless you have the same lambda for all resolvers? In fact, I already contacted AWS concerning that. I think that the context parameter of the lambda should give the graphQl path it resolves for out of the box.

bboure avatar Jan 30 '19 10:01 bboure

@honkskillet Would something like this be what you are looking for?

- dataSource: mySource
  type: Query
  field: field
  templates: "myTemplates.vtl"
## BEGIN REQUEST
{ ## addPost-request-mapping-template.txt
    "version" : "2017-02-28",
    "operation": "Invoke",
    "payload": {
        "field": "addPost",
        "arguments":  $util.toJson($context.arguments)
    }
}
## END REQUEST

## BEGIN RESPONSE
$util.toJson($context.result)
## END RESPONSE

Then the plugin would extract both templates and use accordingly.

This is an idea we could consider I guess

bboure avatar Feb 25 '19 22:02 bboure

One alternate way to handle this is to keep "common responses" apart form the type specific request templates.

- dataSource: myDSN
  type: Query
  field: getFoo
  request: foo/Query.getFoo.vtl
  response: common/One.response.vtl
- dataSource: myDSN
  type: Query
  field: getBar
  request: bar/Query.getBar.vtl
  response: common/One.response.vtl
- dataSource: myDSN
  type: Query
  field: listBar
  request: bar/Query.listBar.vtl
  response: common/Many.response.vtl

I keep a common set of response templates for "One" item, and another for "Many" items. Between these two I find that it solves 99% of my situations without any repetition.

cameroncf avatar Apr 10 '19 16:04 cameroncf