Sessions
HTTP does not remember previous requests: each one arrives as if from a new visitor. A session is storage for one visitor's data between requests. The browser gets a cookie with the session id, and the server finds the data by it. Flash messages, form errors and user login all run on sessions.
Settings
The @adonisjs/session package is already installed in the Web kit. A variable in .env sets where data is stored:
SESSION_DRIVER=cookie| Driver | Where the data lives |
|---|---|
cookie | In an encrypted cookie on the visitor's side |
file | In files on the server |
redis | In Redis |
memory | In process memory, for tests only |
The session lifetime and the cookie name are set in config/session.ts.
Writing and reading
The session object is in the request context. Let us make a counter of viewed posts:
// app/controllers/posts_controller.ts
async show({ params, session, view }: HttpContext) {
const post = await Post.findOrFail(params.id)
const viewed = session.get('viewedCount', 0)
session.put('viewedCount', viewed + 1)
return view.render('pages/posts/show', { post, viewed: viewed + 1 })
}get returns the value or the default, put stores a new one. Print {{ viewed }} in the template and open several posts — the number grows. In another browser the count starts over: it has its own session.
Session methods
| Method | What it does |
|---|---|
session.put('key', value) | Store a value |
session.get('key', default) | Read a value |
session.has('key') | Check whether a key exists |
session.forget('key') | Remove a key |
session.pull('key') | Read and remove at once |
session.all() | All session data |
session.flash('key', value) | Store until the next request |
A "recently viewed" list
A session can hold arrays and objects:
// app/controllers/posts_controller.ts
const recent: number[] = session.get('recentPosts', [])
const updated = [post.id, ...recent.filter((id) => id !== post.id)].slice(0, 5)
session.put('recentPosts', updated)The session keeps the ids of the last five opened posts, the newest first. With them you can easily show a "You recently read" block using Post.query().whereIn('id', updated).
The session in a template
Flash messages are printed with the @flashMessage tag, as in the previous lesson. Pass other data to the template from the controller explicitly — that way it is clear where it comes from.
Common mistake
With the cookie driver all session data sits in one cookie, and browsers accept cookies of no more than 4 KB. If you put whole models or long lists into the session, the data stops being saved. Keep only small values in the session — ids, flags — and get the rest from the database. For larger data switch SESSION_DRIVER to file or redis.