Skip to main content

API gateway

Hypi's API gateway acts as a middleware that simplifies the integration of your app with other services.

Importantly, by using the Hypi gateway, you can integrate external services with your Hypi app as if they were a part of the platform.

Hypi's features such as authorisation can all be mixed with gateway functions.

Using the API gateway

API gateway is a part of App-core. It is available to use by default.

@http directive

Hypi's API gateway is centered around a directive, namely @http. To integrate an API you add the directive to a query or mutation function in your app's schema.

Once you have added the directive to a function, it can be treated like any other function in Hypi. Instead of getting its data from the Hypi platform or serverless function, it will get its data from the HTTP service you've configured it to.

Definition and parameters

directive @http(  method: HttpMethod! = GET,  url: String!,  headers: String,  requestTemplate: String,  inline: InlineHttpRequestTemplate, saveAs: String) on FIELD_DEFINITION

HTTP query gets configured with the following parameters.

ParameterDescriptionExample
methodOne of the available HTTP methodsGET, PUT, POST, DELETE, PATCH, OPTIONS, HEAD, TRACE
urlThe URL template to make the requestURL to make request to
headersThe string formatted JSON object which sets the headers sent in the HTTP request. A JSON object where ALL entries MUST be strings or convertible to strings (basically numbers) #e.g. {"a": "v1", "b": 2}{"Authorization":"Bearer ${settings.apiToken}"}
requestTemplateThe name of the request template which defines how the request body and response should be handled
inlineProvides the body of RequestTemplate and ResponseTemplate
saveAsIf present, the HTTP response will be stored in Hypi as the given type. The type must exist in the current instance

A sample URL could be as follows: https://api.my-domain.com/users?$\{settings.userId}&includeAge=\${vars.includeAge}

Here query parameters could be passed using variables 'vars' and 'settings'. Utilities like JSON and MAP are available to use in all the templates like Groovy or Velocity.

Variables

Each argument is a valid Velocity template meaning you can use dynamic parameters. The following may be referenced: "vars", "settings","response".

  • vars refers to any arguments on the field the directive is applied to. ${vars.firstName} refers to the firstName argument of the field. So, pass on the variables through 'vars'.
  • settings refers to any instance settings provided in the app. You may save specific settings in the form of Environment Variable. And then use it in the HTTP request. \${settings.APITOKEN refers to environment variable settings APITOKEN .
  • response refers to the response of the http request that is available in responseTemplate. It contains the entire response of the http request. You may tailor it as required.

Utilities

JSON and Map utilities are available for use in all templates.

  • JsonNode JSON.parseJSON(String)
  • Map<String, Object>; JSON.parse(String)

Map is the standard Java Map interface containing static util methods e.g. Map.of(...) JsonNode is a class used to represent JSON values by the Jackson JSON library.

RequestTemplate

RequestTemplate data type defines the templates that should be applied to a given HTTP request. It contains the name of the request and formats of the request and response. Sometimes the url has a specific request format. You may match that format using the RequestTemplate. Similarly, you may tailor the response received using ResponseTemplate.

RequestTemplate can be referenced by name using the parameter requestTemplate You may create an object of RequestTemplate in the GraphQL editor and then execute HTTP request or you may specify the RequestTemplate inline in the Schema using the parameter inline.

We will look at both these use-cases in the Example. Please note you may run the HTTP request without this template if there is no specific requirement.

type RequestTemplate{
name:String!
request:String
response:String
}

InlineHttpRequestTemplate

InlineHttpRequestTemplate data type can be used to provide the body of the requestTemplate instead of referencing a request template by name. If the structure is static, variable inline can be used which has InlineHttpRequestTemplate data type.

You may tailor the response received by processing responseTemplate string.

input InlineHttpRequestTemplate {  
requestTemplate: String
responseTemplate: String
}

Example:

inline: {
requestTemplate: """{"to": "${vars.email}","notification" :
{"title" : "$vars.title", "body": "$vars.body"}}""",
responseTemplate: """..."""}
}

Example

Let's use directive @http and send an HTTP request to the website https://httpbin.org. It echos the HTTP request back as a response.

Use-Case:1

In this use-case, we will define requestTemplate and responseTemplate using inline variable.

Here is the schema for the HTTP request. It sends the http POST request to the url containing the username and email-id using setEmail function.

type Mutation {
# {emailid: "value emailid", user: "value user"}
setEmail(emailid: String, user: String): Json @http(

method: POST,
url: "https://httpbin.org/post?user=$vars.user&emailid=$vars.emailid",
headers: """{"Content-Type": "application/json",
"Authorization": "$\{settings.APITOKEN}"}"""
inline: {
requestTemplate: """{"email": "${vars.emailid}"}""",
#Notice the use of .textValue() method-this gets the string value without quotes
responseTemplate: """{"value": "$!{response.json.email.textValue()}"}"""
#OR - the below - notice there is no quote around the variable
#Hypi uses the Java Jackson JSON library which will automatically include quotes like this "<value here>"
#responseTemplate: """{"value": $!{response.json.email}}"""
},
saveAs: "Email"
)
}

The requestTemplate has the $vars.emailid field that holds the input email id to be sent across. The responseTemplate extracts the echoed email value from thejson field of the response and saves it in the value field of the Email data type. Notice the use of APITOKEN environment variable. The value of this field has to be set at runtime and the same gets sent over in the HTTP request header.

Let's run the http request now by executing the setEmail function. The response gets saved in the Email object.

mutation{
setEmail(emailid: "[email protected]", user: "abc3")
}

You may cross-check the response in the Email object by using the find function.

Use-Case:2

In this use-case, we will create the RequestTemplate object in the GraphQL editor and format the request. Let's create requestTemplate - httpbin-post.

mutation{  
upsert(values:{
RequestTemplate:[
{
name:"httpbin-post",
request: """{"id": "${vars.emailid}"}"""
}
]
}){
id
}
}

Here is the schema for the HTTP request. Here we are using requestTemplate parameter instead of inline.

type HttpBinResponse2 {
args: Json
data: String
headers: Json
files: Json
form: Json
json: Json
origin: String
url: String
}

type Mutation {
setEmail(emailid: String, user: String): Json @http(
method: POST,
headers: """{"Content-Type": "application/json"}"""
url: "https://httpbin.org/post?user=$vars.user&emailid=$vars.emailid",
requestTemplate: "httpbin-post",
saveAs: "HttpBinResponse2"
)
}

$vars.emailid holds the input email id to be sent across. The same has been used in the requestTemplate -httpbin-post. So only emailid will be echoed back and not the user string as we have omitted it in the requestTemplate. HttpBinResponse2 is the data type that holds the response of the website to the http request.

Let's run the HTTP request now by executing the setEmail function. The response gets saved in the HttpBinResponse2 object. Notice the headers setting echoed in the response.

mutation{
setEmail(emailid: "[email protected]", user: "abc3")
}

You may cross-check the response in the HttpBinResponse2 object by using the find function.