Skip to content
Daniel Molina edited this page Mar 7, 2017 · 36 revisions

Welcome to the statham-serverless wiki!

This is the typical scenario when using Statham Serverless:

Statham-flow

On this scenario we could find three differents cases that makes Statham acts in three different ways:

  • The App1 send a request to the App2 and it receives and process it perfectly
    On this case, the App2 would response to Statham that the request is OK with an required two hundred and - status code [3]. In this way, Statham will interprate that as a successful communication and will notify that to the App1 [4]. As below:
{
  "Status": "The request was processed successfully.",
  "Response": "<RESPONSE_FROM_APP2>"
}
  • The App1 send a bad request and the App2 receives it but can't process it
    On this case, the App2 would response to Statham that receives a bad request with an required four hundred and - status code [3]. With that code, Statham is configured to don't try to resend the message later and directly send the error in the response [4] and in an email to the addresses registered in SES.

The response on [4] would be as follows:

{
  "Status": "The request contains incorrect syntax or can't be processed.",
  "Response": "<RESPONSE_FROM_APP2>"
}
  • The App1 send a request but The App2 didn't receive it
    The main reason of this serverless application is based on this case. Statham will know when a message didn't arrived based on the status code of the request response.
    For example: The App1 send a message with an URL destination that doesn't exist at that moment. When Sthatam try to send that message, it will terminate with a 400 status code. Thus, Statham will store that message on the SQS to try to send it later.

The response of Statham [4] to the App1 in this case will be:

{
  "Status": "The request don't arrived, therefore it was added to the queue.",
  "Response": "<RESPONSE_FROM_APP2>"
}

Status Codes

Statham discriminate between code responses. Its extremely important that the App2 handle in a good way the code responses for this three cases.

Available Endpoints

  • POST - /receive: Main endpoint of the app. In this endpoint, Statham receives a message from a sender app and tries to deliver it to the corresponding destination app.
  • GET - /receive: Same as above but passing the parameters as QueryString and with an HTML response.
  • GET - /getToken: Endpoint to get a JWT passing the password specified in credentials.json

Sending a message

Obtain JWT Token through /getToken

First, you need a JSON Web Token to send messages to statham. To get this, you have to do a HTTP GET request to /getToken endpoint with the following header:

{
  "Authorization": "<YOUR_SECRET_JWT_PASSWORD>"
}

You will find it into credentials.json file.

OK response example:

{
  "token": "<A_LOT_OF_CHARACTERS>"
}

Sending request to /receive

Statham provides an API Endpoint to send messages through an HTTP POST call to /receive. The request has to be as follows:

Header

{
  "Authorization": "<JWT_TOKEN>",
  "Content-Type": "application/json"
}

Body

{
  "method": "POST | GET",
  "url": "https://your-destination-direction/resource",
  "body": "JSON_OBJECT | STRING"
}

Also, you can send a message through an HTTP GET method call to /receive. By sending it in this way, you have to add the four needed parameters as query string parameters.

Example:
GET https://example-host/dev/receive?url=sample.com&token=extoken&body=jsonbody

Ruby example of implementation

Here is an ruby example of implementation of sending a message to Statham by creating a service that have two methods, one for request the JSON Web Token and another to send the message:

class StathamService
  require 'net/https'

  def token
    puts "getting token"
    @token ||= begin
      url_token                 = Settings.statham.token
      uri                       = URI.parse(url_token)
      request                   = Net::HTTP::Get.new(uri.path)
      request['Authorization']  = Settings.statham.password
      http                      = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl              = true if Rails.env.production?
      response                  = http.request(request)
      token                     = JSON.parse(response.body) if response.body.present?
      token['token'] if token.present?
    end
  end

  def self.send_to_statham body, method, url
    data                      = { body: body, method: method, url: url }
    uri                       = URI.parse(Settings.statham.receive)
    http                      = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl              = true if Rails.env.production?
    request                   = Net::HTTP::Post.new(uri.request_uri, 'Content-Type' =>'application/json')
    request['Authorization']  = token
    request.body              = data.to_json
    response                  = http.request(request)
    response
  end

end