Navigation

HTTP Service

The HTTP service in MongoDB Stitch enables you to integrate Stitch apps with any third-party service that provides a REST API over HTTP, such as Slack, or your own custom service.

You can use the HTTP service to make outgoing HTTP requests to these services, or you can use the HTTP service to create incoming webhooks that respond to incoming HTTP requests.

Add an HTTP Service

To set up an HTTP service in MongoDB Stitch:

  1. Click Services in the left navigation pane and click Add a Service.
  2. Select HTTP.
  3. Enter a name for your service in the Service Name box.
  4. Click Add Service.

Service Actions

The HTTP service in MongoDB Stitch provides the following actions which are available in functions and in the SDKs. These actions can be used to make outgoing HTTP requests.

Action Description
httpService.get() Corresponds to the HTTP method GET.
httpService.post() Corresponds to the HTTP method POST.
httpService.delete() Corresponds to the HTTP method DELETE.
httpService.put() Corresponds to the HTTP method PUT.
httpService.patch() Corresponds to the HTTP method PATCH.
httpService.head() Corresponds to the HTTP method HEAD.

For general information on service actions and how to use them, see Service Actions.

Service Rules

You must specify rules to enable the HTTP service actions. A rule must evaluate to true to enable the action. For general information on service rule construction and syntax, see Service Rules.

Permitted Arguments

The following arguments are permitted in HTTP service rules, and they can be accessed with the "%%args" expansion:

url

The url argument is a JSON document whose fields correspond to the components of a URL.

Given the URL of the form:

<scheme>://<host>/<path>?<query>#<fragment>

The url argument is a document with the fields:

{
   "scheme": <string>,
   "host": <string>,
   "path": <string>,
   "query": <string>,
   "fragment": <string>
}
  • The host can include the port.
  • The path includes the leading slash /.
  • The query excludes the question mark ?.
  • The fragment excludes the hash sign #.

That is, given the following URL as the argument to a GET action:

https://mongodb.example.net/api/v1.0/entity/foobar?status=OPEN&pageNum=2

The corresponding url document would contain:

{
   "scheme": "https",
   "host": "mongodb.example.net",
   "path": "/api/v1.0/entity/foobar",
   "query": "status=OPEN&pageNum=2"
}

headers

The headers argument is a document whose fields corresponds to the HTTP header fields and the corresponding values are an array of values (e.g. "Content-Type": [ "application/json" ]) for the request.

body

The body argument is a document that corresponds to the body of the HTTP request.

followRedirects

The followRedirects argument is a boolean that determines whether or not to follow redirects.

cookies

The cookies argument is a document containing the cookie name and value pairs.

Note

If specifying a rule with a particular cookie, use %%args.cookies.<field>

authUrl

The authUrl argument is a document that corresponds to the authURL for the HTTP request.

Given the auth URL is the following:

<scheme>://<host>/<path>?<query>#<fragment>

Then, the authURL argument is a document with the fields:

{
   "scheme": <string>,
   "host": <string>,
   "path": <string>,
   "query": <string>,
   "fragment": <string>
}
  • The host can include the port.
  • The path includes the leading slash /.
  • The query excludes the question mark ?.
  • The fragment excludes the hash sign #.

For example, given the following URL as the argument to a GET action:

https://sometest.example.com/api/oauth2/authorize?prompt=consent&response_type=code

The corresponding authURL document would contain:

{
   "scheme": "https",
   "host": "sometest.example.com",
   "path": "/api/oauth2/authorize",
   "query": "prompt=consent&response_type=code"
}

Examples

Example Rule with the url Argument

Actions When
get
patch
{
  "%%args.url.host" : "mongodb.example.net",
  "%%args.url.path" : "/api/v1.0/entity/foobar"
}

The HTTP rule ensures that applications can perform a GET or a PATCH when:

  • url host is "cloud.mongodb.com" and
  • url path is "/api/v1.0/entity/foobar"

Example Rule with the headers Argument

Actions When
patch
{
  "url.host" : "mongodb.example.net",
  "url.path" : "/api/v1.0/entity/foobar",
  "headers.Content-Type": "application/json"
}

The HTTP rule ensures that applications can only perform a PATCH action when the:

  • url host is "cloud.mongodb.com",
  • url path is "/api/v1.0/entity/foobar", and
  • content type is "application/json"

Example Rule with the body Argument

Actions When
patch
{
  "url.host" : "mongodb.example.net",
  "url.path" : "/api/v1.0/entity/foobar",
  "headers.Content-Type": "application/json",
  "body.name": { "%exists": 1 }
}

The HTTP rule ensures that applications can only perform a PATCH action when the:

  • url host is "mongodb.example.net",
  • url path is "/api/v1.0/entity/foobar",
  • content type is "application/json", and
  • body contains the field name.

Example Rule with the followRedirects Argument

Actions When
post
{
  "%%args.url.host" : "mongodb.example.net",
  "%%args.url.path" : "/api/v1.0/entity/foobar",
  "%%args.followRedirects": false
}

The HTTP rule ensures that applications can only perform a post action when the:

  • url host is "mongodb.example.net",
  • url path is "/api/v1.0/entity/foobar", and
  • followRedirects is false.

Example Rule with the cookies Argument

Actions When
get
{
  "url.host" : "mongodb.example.net",
  "url.path" : "/api/v1.0/entity/foobar",
  "cookies.language-selected": "python"
}

The HTTP rule ensures that applications can only perform a get action when the:

  • url host is "mongodb.example.net",
  • url path is "/api/v1.0/entity/foobar", and
  • cookie language-selected is "python"

Incoming Webhooks

Incoming webhooks allow you to expose Stitch functions to third-party services via a callback URL. This is useful for responding to events from third parties or returning data from MongoDB without using a Stitch SDK.

To trigger the webhook function, third parties simply need to send an HTTP request to the webhook URL. For more information on creating and triggering webhooks, see the documentation for Service Webhooks.

Modify a Webhook Response

If Respond with Result is enabled for a particular webhook, an HTTP Response will be returned to the third party that called the webhook. By default, the response’s body field is set to the return value of the webhook function.

It’s possible configure the webhook response from within the webhook function. When a webhook is called, a response object is automatically passed as a second argument to the webhook function. The response object has a set of built-in methods that allow you to set the response’s headers, body, and status code. Calling any of these methods will override the default response behavior.

exports = function(payload, response) {
  /* Database operations, service interactions,
     and other logic happens here */

  response.setStatusCode(200);
  response.setBody("This is the response body!");

  // This return does nothing because the response has been directly edited.
  return "foo"
};

The following table lists the available methods for modifying the response object:

Method Arguments Description
setStatusCode(code) code integer

Set the HTTP response status code.

Example

response.setStatusCode(201);
setBody(body) body string or BSON.Binary

Set the HTTP response body.

If body is a string, it will be encoded to BSON.Binary before being returned.

Example

response.setBody(
  "{'message': 'Hello, World!'}"
);
setHeader(name, value)
name string
value string

Set the HTTP response header specified by name to the value passed in the value argument. This overrides any other values that may have already been assigned to that header.

Example

response.setHeader(
  "Content-Type",
  "application/json"
);
addHeader(name, value)
name string
value string

Set the HTTP response header specified by name to the value passed in the value argument. Unlike setHeader, this does not override other values that have already been assigned to the header.

Example

response.addHeader(
  "Cache-Control",
  "max-age=600"
);

response.addHeader(
  "Cache-Control",
  "min-fresh=60"
)

Note

The response object is only passed automatically by real webhook requests. To manually test the response object from the function console, pass a new HTTPResponse as the second argument to exports():

exports(payload, new HTTPResponse())

Validate a Webhook Request

To validate that a webhook request is coming from a trusted source, the third-party service that sends the request must provide some form of validation. There are two Request Validation options:

Verify Payload Signature (See an Example)
Require that incoming requests sign the message with an HMAC hash value generated from the request body and secret string. The hash should be hexadecimal-encoded and generated with the SHA-256 algorithm.
Require Secret as Query Param (See an Example)
Require that incoming requests include the specified secret string as a query parameter appended to the end of the URL.

Note

For maximum security, programmatically generate the secret string using a secure package such as the Python secrets module.

Example: Signing Message Payload

To validate the request, Verify Payload Signature requires that we generate a hexadecimal-encoded HMAC SHA-256 hash based on the request body and secret string.

Consider the following webhook request body and secret:

body = {"message":"MESSAGE"}
secret = 12345

The following Python code generates the hash for this body and secret:

import hashlib;
import hmac;
secret = b'12345'
body = b'{"message":"MESSAGE"}'
hash = hmac.new(secret, body, hashlib.sha256)
print(hash.hexdigest())

# > Output: 828ee180512eaf8a6229eda7eea72323f68e9c0f0093b11a578b0544c5777862

The hash value must be assigned to the X-Stitch-Signature HTTP request header on every request:

X-Hook-Signature:sha256=<hex-encoded-hash>

To test that the request was properly signed, we could run the following curl command:

curl -X POST \
     -H "Content-Type: application/json" \
     -H "X-Hook-Signature:sha256=828ee180512eaf8a6229eda7eea72323f68e9c0f0093b11a578b0544c5777862" \
     -d '{"message":"MESSAGE"}' \
     <webhook URL>

Note

<webhook URL> should be replaced with the actual incoming webhook URL, including any other query parameters as appropriate.

See also

Example: Secret Query Parameter

To validate requests with the Require Secret as Query Param option, incoming requests must include the specified secret string as the value of the secret query parameter.

Consider a webhook configured to use a secret value of 12345. All requests must be made to the webhook URL appended with the secret as a query parameter:

<webhook URL>?secret=secret

To test that requests to this URL are properly verified, we could run the following curl command:

curl -H "Content-Type: application/json" \
     -d '{ "message": "HELLO" }' \
     -X POST '<webhook URL>?secret=12345'

Note

<webhook URL> should be replaced with the actual incoming webhook URL, including any other query parameters as appropriate.

Example Webhook Function

The following webhook function inserts incoming data into a MongoDB collection and returns the insertedId in the response body.

exports = function(payload, response) {
  const mongodb = context.services.get("mongodb-atlas");
  const requestLogs = mongodb.db("test").collection("requestlogs");
  requestLogs.insertOne({
    body: EJSON.parse(payload.body.text()),
    query: payload.query
  }).then(result => {
    response.setStatusCode(201);
    response.setBody(result.insertedId);
  })
};