To store useful session data in Redis database, we can use the third party package called “Deno Sessions” at https://deno.land/x/sessions@v1.5.4 by adding this link to the list of packages in deps.ts module.

 

// deps.ts

export {
    dirname,
    fromFileUrl,
    join,
} from "https://deno.land/std@0.151.0/path/mod.ts";
export {
    json,
    opine,
    Router,
    serveStatic,
    urlencoded,
} from "https://deno.land/x/opine@2.2.0/mod.ts";

export { config } from "https://deno.land/std@0.147.0/dotenv/mod.ts";
export { Bson, MongoClient } from "https://deno.land/x/mongo@v0.30.1/mod.ts";
export { connect } from 'https://deno.land/x/redis@v0.26.0/mod.ts';
export { OpineSession, RedisStore } from "https://deno.land/x/sessions@v1.5.4/mod.ts";

 

However, this package does not support Redis database at Redis Enterprise platform yet, it supports only the standalone Redis Open Source. To use this package, we need to do a small modification by subclassing its RedisStore class in view to override its init( ) method.

 

// setting.js

function setting(){
    const configure = {
        site_title: "Ever Job",
        page_title: "Home",
        message: "",
        dasPostAmount: 10,
        homePostAmount: 12,
    }

    return configure;
}


import { config } from "./deps.ts";
await config({export: true});
 
 
import { MongoClient } from "./deps.ts";
const client = await new MongoClient();
await client.connect(Deno.env.get('DATABASE_URI'));
const mydb = client.database(Deno.env.get('DB_NAME'));
 
 
import { connect } from "./deps.ts";
const myredis = await connect({
    hostname: Deno.env.get('REDIS_URI'),
    port: parseInt(Deno.env.get('REDIS_PORT')),
    password: Deno.env.get('REDIS_PASSWORD'),
});


import { OpineSession, RedisStore } from "./deps.ts";
class _RediStore extends RedisStore{
    async init(){
        this.db = await myredis;
    }
};
const session_store = new _RediStore({});
await session_store.init();


export { setting, mydb, session_store, OpineSession }; 

 

To create a session and store it in the request object to be used across different modules later, we should do as below:

 

// app.ts

import {
    dirname,
    fromFileUrl,
    join,
    json,
    opine,
    serveStatic,
    urlencoded,
} from "./deps.ts";

import indexRouter from "./routes/index.ts";
import usersRouter from "./routes/users.ts";

const app = opine();

import { 
    setting, 
    mydb, 
    session_store, 
    OpineSession, 
} from "./setting.js";

const session = new OpineSession(app, {}, session_store);

app.use(async (req, res, next) => {
    req.mydb = await mydb;
    req.mysetting = await setting;
    req.mysession = session;
    next();
});

const __dirname = fromFileUrl(dirname(import.meta.url));

// Handle different incoming body types
app.use(json());
app.use(urlencoded());

// Serve our static assets
app.use(serveStatic(join(__dirname, "public")));

// Mount our routers
app.use("/", indexRouter);
app.use("/users", usersRouter);  

export default app;

 

GitHub: https://github.com/Sokhavuth/opine-job 

Deno Deploy: https://khmerweb-job.deno.dev