Is it possible to run a REST API with a worker?

I've been trying to build a fairly basic API on a worker using the Hono framework.
But I've been hitting wall after wall, mostly with the fact that workers (wrangler) do not work with standard node env variables. I've read the documentation on worker Environment Variables at least 10 time.. but for whatever reason the context of my app design just wont play nice with this way of passing envars Here's My entry point
import { Hono } from "hono";
import { logger } from "hono/logger";
import { prettyJSON } from "hono/pretty-json";
import { cors } from "hono/cors";
//
import connectDB from "./config/db";
import { Users } from "./routes";
import { errorHandler, notFound } from "./middlewares";

// Initialize the Hono app
const app = new Hono().basePath("/api/v1");


// Config MongoDB
connectDB();

// Initialize middlewares
app.use("*", logger(), prettyJSON());

// Cors
app.use(
"*",
cors({
origin: "*",
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
})
);

// Home Route
app.get("/", (c) => c.text("Welcome to the API!"));

// User Routes
app.route("/users", Users);

// Error Handler
app.onError((err, c) => {
const error = errorHandler(c);
return error;
});

// Not Found Handler
app.notFound((c) => {
const error = notFound(c);
return error;
});

const port = 8000;

export default {
port,
fetch: app.fetch,
};
import { Hono } from "hono";
import { logger } from "hono/logger";
import { prettyJSON } from "hono/pretty-json";
import { cors } from "hono/cors";
//
import connectDB from "./config/db";
import { Users } from "./routes";
import { errorHandler, notFound } from "./middlewares";

// Initialize the Hono app
const app = new Hono().basePath("/api/v1");


// Config MongoDB
connectDB();

// Initialize middlewares
app.use("*", logger(), prettyJSON());

// Cors
app.use(
"*",
cors({
origin: "*",
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
})
);

// Home Route
app.get("/", (c) => c.text("Welcome to the API!"));

// User Routes
app.route("/users", Users);

// Error Handler
app.onError((err, c) => {
const error = errorHandler(c);
return error;
});

// Not Found Handler
app.notFound((c) => {
const error = notFound(c);
return error;
});

const port = 8000;

export default {
port,
fetch: app.fetch,
};
And here's a module that handles connecting to the database
import * as mongoose from 'mongoose'

const connectDB = async () => {
try {
if (MONGO_URI !== undefined) {
//I've tried to do vars several ways as follows
// Appears to be valid code in the sense that resolves to my string
const conn = await mongoose.connect(MONGO_URI, {
//IIRC this complains that $ is undefied
const conn = await mongoose.connect(${env.MONGO_URI}, {
//This throws an error that env is undefied, and no mwater what i've tried in the entry i can't get it to pass
const conn = await mongoose.connect(`${env.MONGO_URI}`, {
autoIndex: true,
})

console.log(`MongoDB Connected: ${conn.connection.host}`)
console.log(MONGO_URI)
}
} catch (err: any) {
console.error(`Error: ${err.message}`)
process.exit(1)
}
}

export default connectDB
import * as mongoose from 'mongoose'

const connectDB = async () => {
try {
if (MONGO_URI !== undefined) {
//I've tried to do vars several ways as follows
// Appears to be valid code in the sense that resolves to my string
const conn = await mongoose.connect(MONGO_URI, {
//IIRC this complains that $ is undefied
const conn = await mongoose.connect(${env.MONGO_URI}, {
//This throws an error that env is undefied, and no mwater what i've tried in the entry i can't get it to pass
const conn = await mongoose.connect(`${env.MONGO_URI}`, {
autoIndex: true,
})

console.log(`MongoDB Connected: ${conn.connection.host}`)
console.log(MONGO_URI)
}
} catch (err: any) {
console.error(`Error: ${err.message}`)
process.exit(1)
}
}

export default connectDB
Am i just chasing my tail for no reason here? is this something explicitly disabled or prevented on workers? Am i misunderstanding the usecase? would this be better suited on pages? or is this just not something CF intends us to use at all?
4 Replies
Hard@Work
Hard@Work4d ago
For one, you don't provide a port when running Workers. The second is you shouldn't be initializing the Database Connection in the global scope
Hurby
Hurby4d ago
Also I don’t think it is possible use mongoose in cf environment
downeydabber
downeydabber2d ago
And even if it was, using a DB connection like this in a stateless / serverless runtime is a terrible idea
downeydabber
downeydabber2d ago
Environment variables are attached to the request, so you can't access them outside the scope of the request. Like someone else said, creating the database connection in the global scope is not possible due to this. It is also not great to create a long-lasting database connection on workers which are short-lived processes. It is better to make API calls to the database to provide operations. You've said you already read the environment variable docs, but read this page: https://developers.cloudflare.com/workers/configuration/environment-variables/ The env object is how you access variables (env.MONGO_URI in your case) . But that is an argument passed to the request object, so it has to be used within that context.
Cloudflare Docs
Environment variables · Cloudflare Workers docs
Environment variables are a type of binding that allow you to attach text strings or JSON values to your Worker

Did you find this page helpful?