This is the legacy HTTP function reference document pertaining to API Gateway v1 (aka API Gateway "REST" APIs) request/response payloads.
As of September 2020, Begin apps use API Gateway v2 (aka "HTTP" APIs) payloads; this document will be kept in posterity for reference, but is not actively maintained.
For the most up to date documentation on API Gateway v1 REST APIs, please refer to this AWS doc.
The HTTP handler API follows a simple request / response pattern. Let's look at an example of a basic HTTP function:
// src/http/get-index/index.js
let body = `
<!doctype html>
<html lang=en>
<body>
<h1>Hello world!</h1>
</body>
</html>
`
exports.handler = async function http (request) {
return {
statusCode: 200,
headers: { 'content-type': 'text/html; charset=utf8' },
body
}
}
No sweat, right?
The handler
function invoked by a client request receives a request
object containing the following parameters:
httpMethod
- StringGET
, POST
, PATCH
, PUT
, or DELETE
path
- StringpathParameters
- null or Objectfoo
in GET /:foo/bar
)queryStringParameters
- null or Objectheaders
- Objectbody
- null or String (base64-encoded)isBase64Encoded
- Booleanbody
is base64-encoded binary payloadAdditional and extended versions of this and other data may be available in your
request
; for additional documentation, please head here.
Here's an example of an incoming request
object, being handled by the HTTP Function GET /salutations/:greeting
:
// Client requested https://your-domain/salutations/hello-world?testing=123
{
httpMethod: 'GET',
path: '/salutations/hello-world',
headers: {
host: 'begin.com',
connection: 'keep-alive',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
dnt: '1',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-US,en;q=0.9',
Cookie: '_idx=LbyL0kPK2xOLfdm_WnESzlsG.8kStzevVXstnEkosp0k5PK2xOz3e820NtoEx1b3VXnEC8'
},
queryStringParameters: { testing: '123' },
pathParameters: { greeting: 'hello-world' },
body: null,
isBase64Encoded: false
}
All bodies are unparsed, base64-encoded strings; you can parse and process these however you please, but @architect/functions
has a convenient method for doing so. Here's an example:
// POST body includes form URL-encoded string: 'greeting=howdy'
let arc = require('@architect/functions')
let parseBody = arc.http.helpers.bodyParser
exports.handler = async function http (request) {
console.log(request.body) // 'Z3JlZXRpbmc9aG93ZHk='
let body = parseBody(request) // Pass the entire request object
let greeting = body.greeting // 'howdy'
return {
statusCode: 200,
headers: { 'content-type': 'text/html; charset=utf8' },
body: greeting
}
}
Responses are returned by your handler
function in an object, and use the following parameters:
statusCode
- Number200
headers
- Objectbody
- Stringbody
payload size is 6MB; files being delivered non-dynamically should use the Begin CDNisBase64Encoded
- Booleanbody
is base64-encoded binary payload; defaults to false
true
if emitting a binary payloadHere's a simple example response for an API endpoint:
// Responding to a successful POST
return {
statusCode: 201,
headers: { 'content-type': 'application/json; charset=utf8' },
body: JSON.stringify({ok: true}),
}
Many remote networks rely on overly aggressive reverse-proxy caches to conserve bandwidth; the absence of the cache-control
header is often (mis)construed by such networks as tacit permission to aggressively cache responses that often should not be cached. This external, network-level behavior can have serious ramifications for your app.
Because of the highly adverse effects network-level caching can on your application, we strongly suggest that most HTTP Function responses include anti-caching headers – especially when returning HTML
and JSON
responses. For example:
return {
statusCode: 200,
headers: {
'content-type': 'text/html; charset=utf8',
'cache-control': 'no-cache, no-store, must-revalidate, max-age=0, s-maxage=0'
},
body: `This definitely won't be cached.`
}
One of the many benefits of using Begin's runtime library, Architect Functions, is automatic, customizable, content-type aware generation of
cache-control
headers.
Every Begin app comes bundled with Begin Data, an easy to use, fast, durable, highly scalable, and fully managed key-value and document database.
Learn more about integrating Begin Data in your app's Functions!
let begin = require('@architect/functions')
exports.handler = async function http (request) {
let session = await begin.http.session.read(request)
let name = session.name || 'there'
let body = `
<!doctype html>
<html lang=en>
<body>
<h1>Hello ${name}!</h1>
</body>
</html>
`
return {
statusCode: 200,
headers: { 'content-type': 'text/html; charset=utf8' },
body
}
}
exports.handler = async function http (request) {
return {
statusCode: 302,
headers: { location: '/new/path' }
}
}
let data = require('@begin/data')
exports.handler = async function http (request) {
let headers = { 'content-type': 'application/json; charset=utf8' }
if (!request.body.note) {
return {
statusCode: 204,
headers,
body: JSON.stringify({ ok: false })
}
}
else {
let table = 'notes'
let note = request.body.note
await data.set({table, note})
return {
statusCode: 201,
headers,
body: JSON.stringify({ ok: true })
}
}
}