AWS AppSync
AWS AppSync Developer Guide

Resolver Mapping Template Reference for Elasticsearch

The AWS AppSync resolver for Amazon Elasticsearch Service enables you to use GraphQL to store and retrieve data in existing Amazon ES domains in your account. This resolver works by allowing you to map an incoming GraphQL request into an Amazon ES request, and then map the Amazon ES response back to GraphQL. This section describes the mapping templates for the supported Amazon ES operations.

Request Mapping Template

Most Amazon ES request mapping templates have a common structure where just a few pieces change. The following example runs a search against an Amazon ES domain, where documents are of type post and are indexed under id. The search parameters are defined in the body section, with many of the common query clauses being defined in the query field. This example will search for documents containing "Nadia", or "Bailey", or both, in the author field of a document:

{ "version":"2017-02-28", "operation":"GET", "path":"/id/post/_search", "params":{ "headers":{}, "queryString":{}, "body":{ "from":0, "size":50, "query" : { "bool" : { "should" : [ {"match" : { "author" : "Nadia" }}, {"match" : { "author" : "Bailey" }} ] } } } } }

For more information on query options, see the Elasticsearch Query DSL Reference.

Response Mapping Template

As with other data sources, Amazon ES sends a response to AWS AppSync that needs to be converted to GraphQL. The shape of an Amazon ES response can be seen in the Elasticsearch Request Body Search DSL Reference.

Most GraphQL queries are looking for the _source field from an Amazon ES response. Because you can do searches to return either an individual document or a list of documents, there are two common response mapping templates used in Amazon ES:

List of Results

[ #foreach($entry in $context.result.hits.hits) #if( $velocityCount > 1 ) , #end $utils.toJson($entry.get("_source")) #end ]

Individual Item


operation field

(REQUEST Mapping Template only)

HTTP method or verb (GET, POST, PUT, HEAD or DELETE) that AWS AppSync sends to the Amazon ES domain. Both the key and the value must be a string.

"operation" : "PUT"

path field

(REQUEST Mapping Template only)

The search path for an Amazon ES request from AWS AppSync. This forms a URL for the operation's HTTP verb. Both the key and the value must be strings.

"path" : "/indexname/type" "path" : "/indexname/type/_search"

When the mapping template is evaluated, this path is sent as part of the HTTP request, including the Amazon ES domain. For example, the previous example might translate to:


params field

(REQUEST Mapping Template only)

Used to specify what action your search performs, most commonly by setting the query value inside of the body. However, there are several other capabilities that can be configured, such as the formatting of responses.

  • headers

    The header information, as key-value pairs. Both the key and the value must be strings. For example:

    "headers" : { "Content-Type" : "JSON" }

    Note: AWS AppSync currently supports only JSON as a Content-Type.

  • queryString

    Key-value pairs that specify common options, such as code formatting for JSON responses. Both the key and the value must be a string. For example, if you want to get pretty-formatted JSON, you would use:

    "queryString" : { "pretty" : "true" }
  • body

    This is the main part of your request, allowing AWS AppSync to craft a well-formed search request to your Amazon ES domain. The key must be a string comprised of an object. A couple of demonstrations are shown below.

Example 1

Return all documents with a city matching "seattle":

"body":{ "from":0, "size":50, "query" : { "match" : { "city" : "seattle" } } }

Example 2

Return all documents matching "washington" as the city or the state:

"body":{ "from":0, "size":50, "query" : { "multi_match" : { "query" : "washington", "fields" : ["city", "state"] } } }

Passing Variables

(REQUEST Mapping Template only)

You can also pass variables as part of evaluation in the VTL statement. For example, suppose you had a GraphQL query such as the following:

query { searchForState(state: "washington"){ ... } }

The mapping template could take the state as an argument:

"body":{ "from":0, "size":50, "query" : { "multi_match" : { "query" : "$context.arguments.state", "fields" : ["city", "state"] } } }

For a list of utilities you can include in the VTL, see Access Request Headers.