Superface Map

Current Working Draft

Introduction

Superface map is a format describing one concrete implementation of a Superface profile. It essentially maps the application (business) semantics into provider’s interface implementation.

1Map Document

Defines a document that maps a profile into a particular provider’s API. At minimum, the map document consists of the profile and provider identifiers and a profile use‐case map.

Optionally, map document may specify a variant. Variant allows for mutliple maps for the same MapProfileIdentifier and ProviderIdentifier.

Example № 1profile = "conversation/send-message"
provider = "some-telco-api"

map SendMessage {
  ...
}

map RetrieveMessageStatus {
  ...
}
Example № 2profile = "conversation/send-message"
provider = "some-telco-api"
variant = "my-bugfix"

map SendMessage {
  ...
}

map RetrieveMessageStatus {
  ...
}

2Usecase Map

Map
mapUsecaseName{MapSlotlistopt}
Context Variables

Map context variables :

  • input - User input as stated in the profile
Example № 3map RetrieveMessageStatus {  
  http GET "/chat-api/v2/messages/{input.messageId}/history" {
    response 200 "application/json" {
      map result {
        deliveryStatus = body.history[0].state
      }
    }
  } 
}

2.1Map Result

MapResult
returnoptmap resultConditionoptSetMapResultVariablesopt
Example № 4map GetWeather {
  map result {
    airTemperature = 42  # Sets the value returned to user
  }
}

2.2Map Error

MapError
returnoptmap errorConditionoptSetMapErrorVariablesopt
Example № 5map GetWeather {
  map error {
    title = "Location not found"
  }
}

3Operation

Context Variables

Operation context variables :

Example № 6operation CountArray {
  return {
    answer = "This is the count " + args.array.length
  }
}

3.1Operation Return

Example № 7operation Foo {
  return if (args.condition) {
    message = "I have a condition!"
  }

  return {
    message = "Hello World!"
  }
}

3.2Operation Fail

Example № 8operation Foo {
  fail if (args.condition) {
    errorMessage = "I have failed!"
  }
}

4Set Variables

LHS
VariableNameVariableKeyPathObjectVariablelistopt
VariableKeyPathObjectVariable
KeyNameObjectVariable
Example № 9set {
  variable = 42
}
Example № 10set if (true) {
  variable = 42
}
Example № 11set {
  variable.key = 42
}
Example № 12set {
  variable = call ConvertToCelsius(tempF = 100)
}

5Operation Call

Condition and iteration

When both Condition and Iteration are specified, the condition is evaluated for every element of the iteration.

Context Variables

OperationCallSlot context variables:

  • outcome.data - data as returned by the callee
  • outcome.error - error as returned by the callee
Example № 13operation Bar {
  set {
    variable = 42
  }

  call FooWithArgs(text = `My string ${variable}` some = variable + 2 ) {
    return if (!outcome.error) {
      finalAnswer = "The final answer is " + outcome.data.answer
    }

    fail if (outcome.error) {
      finalAnswer = "There was an error " + outcome.error.message
    }
  }
}
Example № 14map RetrieveCustomers {
  // Local variables
  set {
    filterId = null
  }


  // Step 1
  call FindFilter(filterName = "my-superface-map-filter") if(input.since) {
    // conditional block for setting the variables
    set if (!outcome.error) {
      filterId = outcome.data.filterId
    }
  }

  // Step 2
  call CreateFilter(filterId = filterId) if(input.since && !filterId) {
    set if (!outcome.error) {
      filterId = outcome.data.filterId
    }
  }

  // Step 3
  call RetrieveOrganizations(filterId = filterId) {
    map result if (!outcome.error && outcome.data) {
      customers = outcome.data.customers
    }
  }

  // Step 4
  call Cleanup() if(filterId) {
    // ...
  }
}
Example № 15operation Baz {
  array = [1, 2, 3, 4]
  count = 0
  data = []

  call foreach(x of array) Foo(argument = x) if (x % 2) {
    count = count + 1
    data = data.concat(outcome.data)
  }
}
Note there is a convenient way to call operations in VariableStament. Using the OperationCallShorthand, the example above can be written as:
Example № 16operation Baz {
  array = [1, 2, 3, 4]
  data = call foreach(x of array) Foo(argument = x) if (x % 2)
  count = data.length
}

5.1Operation Call Shorthand

Used as RHS instead of JessieExpression to invoke an Operation in‐place. In the case of success the operation outcome’s data is unbundled and returned by the call. See OperationCall context variable outcome.

Example № 17set {
  someVariable = call Foo
}
Iteration and operation call shorthand

When an iteration is specified ther result of the OperationCallShorthand is always an array.

Example № 18operationOutcome = call SomeOperation()

users = call foreach(user of operationOutcome.users) Foo(user = user) if (operationOutcome)

// Intepretation: 
// `Foo` is called for every `user` of `operationOutcome.users` if the `operationOutcome` is truthy

superusers = call foreach(user of operationOutcome.users) Bar(user = user) if (user.super)

// Intepretation: 
// `Bar` is called for an `user` of `operationOutcome.users` if the `user.super` is truthy

6Outcome

Evaluation of a use‐case map or operation outcome. The outcome definition depends on its context. When specified in the Map context the outcome is defined as SetMapOutcome. When specified in the Operation context the outcome is defined as SetOperationOutcome.

6.1Map Outcome

Outcome in the Map context.

6.2Operation Outcome

Outcome in the Operation context.

7Network Operation

NetworkCall
GraphQLCall

8HTTP Call

HTTPMethod
GETHEADPOSTPUTDELETECONNECTOPTIONSTRACEPATCH
Example № 19map SendMessage {
  http POST "/chat-api/v2/messages" {
    request "application/json" {
      body {
        to = input.to
        channels = ['sms']
        sms.from = input.from
        sms.contentType = 'text'
        sms.text = input.text
      }
    }

    response 200 "application/json" {
      map result {
        messageId = body.messageId
      }
    }
  }
}

Example of HTTP call to a service other than the defaultService.

Example № 20http GET service2 "/users" {
  ...
}

8.1HTTP Transaction

HTTPTransaction
HTTPSecurityoptHTTPRequestoptHTTPResponselistopt

8.2HTTP Security

Example № 21GET "/users" {
  security "api_key_scheme_id"

  response {
    ...
  }
}

If no other HTTPSecurity is provided, the default is none. Explicitly signify public endpoints as none as so.

Example № 22GET "/public-endpoint" {
  security none
  
  response {
    ...
  }
}

8.3HTTP Request

Example № 23http GET "/greeting" {
  request {
    query {
      myName = "John"
    }
  }
}
Example № 24http POST "/users" {
  request "application/json" {
    query {
      parameter = "Hello World!"
    }

    headers {
      "my-header" = 42
    }

    body {
      key = 1
    }
  }
}
Example № 25http POST "/users" {
  request "application/json" {
    body = [1, 2, 3]
  }
}

8.4HTTP Response

HTTPRespose
responseStatusCodeoptContentTypeoptContentLanguageopt{HTTPResponseSlotlistopt}
Context Variables

HTTPResponseSlot context variables :

  • statusCode - HTTP response status code parsed as number
  • headers - HTTP response headers in the form of object
  • body - HTTP response body parsed as JSON
Example № 26http GET "/" {
  response 200 "application/json" {
    map result {
      outputKey = body.someKey
    }
  }
}
Example № 27http POST "/users" {
  response 201 "application/json" {
    return {
      id = body.userId
    }
  }
}

Handling HTTP errors:

Example № 28http POST "/users" {
  response 201 "application/json" {
    ...
  }
  
  response 400 "application/json" {
    error {
      title = "Wrong attributes"
      details = body.message
    }
  }
}

Handling business errors:

Example № 29http POST "/users" {
  response 201 "application/json" {
    map result if(body.ok) {
      ...
    }

    map error if(!body.ok) {
      ...
    }
  }
}

When ContentType is not relevant but ContentLanguage is needed, use the * wildchar in place of the ContentType as follows:

Example № 30http GET "/" {
  response  "*" "en-US" {
    map result {
      rawOutput = body
    }
  }
}

9Conditions

Conditional statement evalutess its JessieExpression for truthiness.

Example № 31if ( true )
Example № 32if ( 1 + 1 )
Example № 33if ( variable % 2 )
Example № 34if ( variable.length == 42 )

10Iterations

When the given JessieExpression evaluates to an array (or any other ECMA Script iterable), this statement iterates over its elements assigning the respective element value to its context VariableName variable.

Example № 35foreach (x of [1, 2, 3])
Example № 36foreach (element of variable.nestedArray)

11Jessie

Define what is Jessie and what expression we support
JessieExpression
JessieScript

12Language

12.1Source text

SourceCharacter
/[\u0009\u000A\u000D\u0020-\uFFFF]/

12.1.1Comments

Example № 37// This is a comment

12.1.2Line Terminators

LineTerminator
New Line (U+000A)
Carriage Return (U+000D)New Line (U+000A)
Carriage Return (U+000D)New Line (U+000A)

12.2Common Definitions

12.2.1Identifier

Identifier
/[_A-Za-z][_0-9A-Za-z]*/

12.2.2Profile Identifier

DocumentNameIdentifier
/[a-z][a-z0-9_-]*/

Identifier of a profile regardless its version.

Example № 38character-information
Example № 39starwars/character-information

12.2.3Full Profile Identifier

Fully disambiguated identifier of a profile including its exact version.

Example № 40character-information@2.0.0
Example № 41starwars/character-information@1.1.0

12.2.4Map Profile Identifier

Profile identifier used in maps does not include the patch number.

Example № 42starwars/character-information@1.1

12.2.5Provider Identifier

12.2.6Service Identifier

12.2.7URL Value

URLValue
"URL"

12.2.8Security Scheme Identifier

References the security scheme found within a provider definition.

12.2.9String Value

12.2.10Integer Value

IntegerValue
/[0-9]+/

AAppendix: Keywords

§Index

  1. Argument
  2. Comment
  3. CommentChar
  4. Condition
  5. ContentLanguage
  6. ContentType
  7. DocumentNameIdentifier
  8. EscapedCharacter
  9. FullProfileIdentifier
  10. HTTPBody
  11. HTTPBodyValueDefinition
  12. HTTPCall
  13. HTTPHeaders
  14. HTTPMethod
  15. HTTPRequest
  16. HTTPRequestBodyAssignment
  17. HTTPRequestSlot
  18. HTTPResponseSlot
  19. HTTPRespose
  20. HTTPSecurity
  21. HTTPStatusCode
  22. HTTPTransaction
  23. Identifier
  24. IntegerValue
  25. Iteration
  26. JessieExpression
  27. KeyName
  28. LHS
  29. LineTerminator
  30. MajorVersion
  31. Map
  32. MapDocument
  33. MapError
  34. MapProfileIdentifier
  35. MapResult
  36. MapSlot
  37. MinorVersion
  38. NetworkCall
  39. Operation
  40. OperationArguments
  41. OperationCall
  42. OperationCallShorthand
  43. OperationCallSlot
  44. OperationFail
  45. OperationName
  46. OperationReturn
  47. OperationSlot
  48. PatchVersion
  49. Profile
  50. ProfileIdentifier
  51. ProfileName
  52. ProfileScope
  53. Provider
  54. ProviderIdentifier
  55. RHS
  56. SecuritySchemeIdentifier
  57. SemanticVersion
  58. ServiceIdentifier
  59. SetMapErrorVariables
  60. SetMapOutcome
  61. SetMapResultVariables
  62. SetOperationFailVariables
  63. SetOperationOutcome
  64. SetOperationReturnVariables
  65. SetOutcome
  66. SetVariables
  67. SourceCharacter
  68. StringCharacter
  69. StringValue
  70. URLPath
  71. URLPathLiteral
  72. URLPathSegment
  73. URLPathVariable
  74. URLQuery
  75. URLTemplate
  76. URLValue
  77. UsecaseName
  78. VariableKeyPath
  79. VariableName
  80. VariableStatement
  81. VariableStatements
  82. Variant
  1. 1Map Document
  2. 2Usecase Map
    1. 2.1Map Result
    2. 2.2Map Error
  3. 3Operation
    1. 3.1Operation Return
    2. 3.2Operation Fail
  4. 4Set Variables
  5. 5Operation Call
    1. 5.1Operation Call Shorthand
  6. 6Outcome
    1. 6.1Map Outcome
    2. 6.2Operation Outcome
  7. 7Network Operation
  8. 8HTTP Call
    1. 8.1HTTP Transaction
    2. 8.2HTTP Security
    3. 8.3HTTP Request
    4. 8.4HTTP Response
  9. 9Conditions
  10. 10Iterations
  11. 11Jessie
  12. 12Language
    1. 12.1Source text
      1. 12.1.1Comments
      2. 12.1.2Line Terminators
    2. 12.2Common Definitions
      1. 12.2.1Identifier
      2. 12.2.2Profile Identifier
      3. 12.2.3Full Profile Identifier
      4. 12.2.4Map Profile Identifier
      5. 12.2.5Provider Identifier
      6. 12.2.6Service Identifier
      7. 12.2.7URL Value
      8. 12.2.8Security Scheme Identifier
      9. 12.2.9String Value
      10. 12.2.10Integer Value
  13. AAppendix: Keywords
  14. §Index