Documentation

Session Adapters

New
Browse documentation

Published 2026-08-13. V2 is a prerelease; the web core is release-gated and other previews are named separately. What beta means.

Read this page as HTML, Markdown, or structured JSON—or open the published Markdown with an AI assistant. Gemini receives the prompt through your clipboard because its signed-out page does not reliably prefill URL text; paste when the new tab opens. External assistants need the public site URL.

1.4.1
Unavailable in this version
1.5
Unavailable in this version

Session Adapters

Session adapters store the key/value data associated with a session ID. Amber V2 includes MemorySessionAdapter; applications can register another backend through AdapterFactory when state must survive a restart or be shared across processes.

Complete adapter contract

A custom adapter inherits Amber::Adapters::SessionAdapter and implements every abstract operation.

Reference API: implemented by a class under src/adapters/, for example src/adapters/redis_session_adapter.cr. Do not copy the abstract class into the application.

Crystal
abstract class Amber::Adapters::SessionAdapter
  abstract def get(session_id : String, key : String) : String?
  abstract def set(session_id : String, key : String, value : String) : Nil
  abstract def delete(session_id : String, key : String) : Nil
  abstract def destroy(session_id : String) : Nil
  abstract def exists?(session_id : String, key : String) : Bool
  abstract def keys(session_id : String) : Array(String)
  abstract def values(session_id : String) : Array(String)
  abstract def to_hash(session_id : String) : Hash(String, String)
  abstract def empty?(session_id : String) : Bool
  abstract def expire(session_id : String, seconds : Int32) : Nil
  abstract def batch_set(session_id : String, values : Hash(String, String)) : Nil
  abstract def batch(session_id : String, &block : Amber::Adapters::SessionBatchOperations ->) : Nil
end

Adapters may also override close to release connections and healthy? to report backend availability.

batch_set and batch should be atomic when the backend supports transactions or pipelining. The expiration operation applies to the complete session, not an individual key.

Built-in memory adapter

File: the applicable file under config/environments/, such as config/environments/development.yml — edit its existing session: section.

YAML
session:
  key: "my_app.session"
  store: "signed_cookie"
  adapter: "memory"
  expires: 3600

Memory state belongs to one application process and disappears when that process stops. Use it for development, tests, or a deployment where that lifecycle is an explicit product decision.

Register an application adapter

Load and register the adapter before Amber builds the configured session store. The generated application entry point requires top-level config/*, including config/application.cr, before application source, so it is a reliable registration point.

File: config/application.cr — keep require "amber", require the adapter class, then register it before routes are loaded.

Crystal
# config/application.cr
require "amber"
require "../src/adapters/redis_session_adapter"

Amber::Adapters::AdapterFactory.register_session_adapter("redis") do
  RedisSessionAdapter.new(redis_client)
end

File: config/environments/production.yml — edit the existing session: section after the adapter is registered.

YAML
# config/environments/production.yml
session:
  key: "my_app.session"
  store: "signed_cookie"
  adapter: "redis"
  expires: 86400

The generated V2 application does not automatically require every file under config/initializers/. If you choose that directory, add an explicit require before Amber::Server.start and prove the load order in a clean build.

Adapter verification

Test the implementation independently from controller behavior:

  • create, read, update, and delete more than one key in a session;
  • distinguish deleting one key from destroying the complete session;
  • return consistent results from keys, values, to_hash, and empty?;
  • expire a session and verify its keys disappear;
  • prove batch_set and batch do not expose a partial update;
  • exercise backend timeout, reconnect, and unavailable states;
  • close connections cleanly during shutdown;
  • run concurrent access tests that match the deployment process model.

For a Redis migration, also preserve or intentionally replace the previous key namespace, serialization, expiration, and active-session policy. See Redis to Adapters.