Sessions

Hyper Text Transfer Protocol (HTTP) is how messages are formatted and transmitted over the internet. So far we've only built applications that utilize HTTP GET which reads information. HTTP POST is how a web browser writes information. You are ready to move beyond HTTP GET requests. The web is rich, interactive and stateful place which is a fancy way of saying we read and write data.

Developing database backed stateful web applications used to require a web server, a database server, a whole supporting cast of software and frameworks and all the near-constant maintenance those things required. Now anyone with a text editor can handle POST requests directly with a Lambda function and API Gateway.

The first primitive to understand for building stateful interactions on the web is session state. HTTP is a stateless protocol which is a fancy way of saying every HTTP request is like a completely clean slate. If we want to remember things between HTTP requests you need a session.

  1. Create a fresh Architect project
mkdir -p ./mysesh
cd mysesh
  1. Create a app.arc file
@app
bigsesh

@http
get /
post /count
post /reset

And generate the boilerplate code by running:

arc init
  1. Add the @architect/functions runtime helper library to your functions. This gives the request object a method to read and write sessions.
cd src/http/get-index
npm init -f
npm i @architect/functions

cd ../post-count
npm init -f
npm i @architect/functions

cd ../post-reset
npm init -f
npm i @architect/functions
  1. Add src/http/get-index/render.js with plain vanilla HTML forms for adding and resetting the session
/** this is perfectly acceptable and FAST server side rendering */
module.exports = function render({count}) {
return `<!doctype html>
<html>
<body>
<form method=post action=/count>
<button>Count
${count}</button>
</form>
<form method=post action=/reset>
<button>Reset</button>
</form>
</body>
</html>
`

}
  1. Modify src/http/get-index/index.js to read the session if it exists and render the forms with the session state
let arc = require('@architect/functions')
let render = require('./render')

async function home(req) {
let count = req.session.count || 0
return {
html: render({ count })
}
}

exports.handler = arc.http.async(home)
  1. Modify src/http/post-count/index.js to mutate the session and redirect home
let arc = require('@architect/functions')

async function counter(req) {
let count = (req.session.count || 0) + 1
return {
session: { count },
location: '/'
}
}

exports.handler = arc.http.async(counter)

FYI: Per recommended security practice Architect applications use httpOnly cookies for storing session state; anyone can implement their own mechanism using Set-Cookie headers directly

  1. Modify src/http/post-reset/index.js to clear the session state
let arc = require('@architect/functions')

async function reset(req) {
return {
session: {},
location: '/'
}
}

exports.handler = arc.http.async(reset)

For more information about arc.http.async helper, check out the documentation

  1. Initialize a package.json in the root of your project, and install @architect/sandbox for a local development server
npm init -f
npm install @architect/sandbox
  1. Add a start command to the scripts section in package.json found at the root of your project
...
"scripts": {
"start": "sandbox"
}
...
  1. Preview by starting the dev server
npm start
  1. Clone the example source:

Deploy to Begin