Session Storage

Session Storage allows to store values associated with the current client session.

The values remain available between different requests and can be used from Page, Action and WebSocket while they belong to the same session.

gox
func GET(ctx *gox.Context) gox.Page {
    var name string

    if exists, err := ctx.Session.Get("name", &name); err != nil || !exists {
        return ctx.Response.DoneWith(403)
    }

    return <p>Hola, {{ name }}</p>
}

The stored values belong only to the current session. To store information shared between different client, use Server Storage.


Structure

ctx.Session provides the following methods to administer Session Storage:

text
Session
{
    Set(key string, value any) error
    Get(key string, out any) (bool, error)
    Has(key string) bool
    GetAll() map[string]any
    Delete(key string) error
    Clear() error
}

Methods

MethodDescription
Set()It stores a value.
Get()Read a value and assign it to the intended destination.
Has()It indicates if a key exists.
GetAll()Returns all stored values.
Delete()It eliminates a value.
Clear()Eliminate all values without destroying the session.

Set()

Firma:func (*Session) Set(key string, value any) error

Set() stores a value using a key.

gox
if err := ctx.Session.Set("name", "George"); err != nil {
    return ctx.Response.DoneWith(500)
}

If the key already exists, its value is replaced.

gox
if err := ctx.Session.Set("language", "en"); err != nil {
    return ctx.Response.DoneWith(500)
}

Set() returns an error when the key is invalid, the session is not available or the adapter cannot store the value.


Get()

Firma:func (*Session) Get(key string, out any) (bool, error)

Get() seeks a value and assigns it to the intended destination.

The destination must be a pointer compatible with the stored value.

gox
var name string

exists, err := ctx.Session.Get("name", &name)

Get() allows a distinction between a non-existing key and a reading that could not be completed:

OutcomeMeaning
exists == true, err == nilThe value exists and was correctly assigned.
exists == false, err == nilThe key doesn't exist.
err != nilThe value could not be assigned or the reading could not be completed.
gox
func GET(ctx *gox.Context) gox.Page {
    var name string

    exists, err := ctx.Session.Get("name", &name)

    if err != nil {
        return ctx.Response.DoneWith(500)
    }

    if !exists {
        return ctx.Response.DoneWith(403)
    }

    return <p>Hola, {{ name }}</p>
}

When the key does not exist, the destination retains its current value.

Get() returns an error if the destination is nil, is not a pointer or is not compatible with the stored value.

GOX supports assignments and conversions between compatible types. However, it is recommended to recover each value using the same type with which it was stored.


Has()

Firma:func (*Session) Has(key string) bool

Has() indicates if a key exists in Session Storage.

gox
func GET(ctx *gox.Context) gox.Page {
    if !ctx.Session.Has("userID") {
        return ctx.Response.DoneWith(403)
    }

    return <p>Sesión autenticada</p>
}

Has() only checks the existence of the key. It does not recover or value its content.

When you also need to use the value, use it directly Get() to avoid consulting the same key twice.


GetAll()

Firma:func (*Session) GetAll() map[string]any

GetAll() returns all values stored in the session.

gox
func GET(ctx *gox.Context) gox.Page {
    values := ctx.Session.GetAll()

    return <p>Total: {{ len(values) }}</p>
}

Each key on the map represents an input from Session Storage.

gox
values := ctx.Session.GetAll()

name := values["name"]
language := values["language"]

The returned map is a separate copy. Modifying it does not change the values stored in the session.

Use Set(), Delete() or Clear() to modify Session Storage.


Delete()

Firma:func (*Session) Delete(key string) error

Delete() removes the value associated with a key.

gox
if err := ctx.Session.Delete("theme"); err != nil {
    return ctx.Response.DoneWith(500)
}

Removing a non-existing key does not make a mistake.

The other values and the identity of the session remain intact.


Clear()

Firma:func (*Session) Clear() error

Clear() removes all stored values without destroying the session.

gox
if err := ctx.Session.Clear(); err != nil {
    return ctx.Response.DoneWith(500)
}

After running Clear(), the session remains active and can store new values.

To permanently delete the session, use Destroy().

See Lifecycle to know the difference between cleaning and destroying a session.


Keys and values

The keys must be strings that contain at least a character other than a space.

gox
if err := ctx.Session.Set("userID", "usr_123"); err != nil {
    return ctx.Response.DoneWith(500)
}

The keys distinguish between capital and lower. For example, "userID" and "userid" they represent different keys.

Set() accepts values by anyincluding primitive types, slices, maps and structures.

gox
type Preferences struct {
    Language string
    Theme    string
}

preferences := Preferences{
    Language: "es",
    Theme:    "dark",
}

if err := ctx.Session.Set("preferences", preferences); err != nil {
    return ctx.Response.DoneWith(500)
}

It uses values that the set-up session adapter can store correctly.


Full example

The following example shows how to store, consult and delete Session Storage values:

gox
func POST(ctx *gox.Context) gox.Action {
    if err := ctx.Session.Set("name", "George"); err != nil {
        return ctx.Response.DoneWith(500)
    }

    if err := ctx.Session.Set("language", "es"); err != nil {
        return ctx.Response.DoneWith(500)
    }

    return ctx.Response.DoneWith(204)
}

func GET(ctx *gox.Context) gox.Page {
    var name string

    if exists, err := ctx.Session.Get("name", &name); err != nil || !exists {
        return ctx.Response.DoneWith(403)
    }

    return <p>Hola, {{ name }}</p>
}

func DELETE(ctx *gox.Context) gox.Action {
    if err := ctx.Session.Delete("name"); err != nil {
        return ctx.Response.DoneWith(500)
    }

    return ctx.Response.DoneWith(204)
}

Best practices

  • It uses descriptive and consistent keys.
  • It recovers each value using the same type with which it was stored.
  • Check the errors returned by Set(), Get(), Delete() and Clear().
  • Use Get() when you need to recover a value and check its existence.
  • Use Has() only when you don't need to recover the value.
  • Avoid storing large amounts of information within a session.
  • Use Delete() to remove a specific value and Clear() to remove all values.
  • It uses Session Storage for information associated with a client and Server Storage for information shared by the server.

See also

Next step

Continue with Lifecycle to know how the sessions are created, recovered, rotated and destroyed.

Lifecycle