This brief summary is best used as companion documentation to support the Hono JS and Drizzle ORM introductory video tutorials.
We create a set of API routes to support operating the user object, which is a sqlite database. We use drizzle ORM to interact with the database.
- connect – Fast, lightweight, and built based on web standards. Supports any JavaScript runtime.
- Drizzle ORM – You can define and manage database schemas in TypeScript, access data in SQL-like or relational ways, and leverage opt-in tools to improve your developer experience.
Installation and setup
Run the command to get started with a basic Hono application, we will focus on the Nodejs setup.
npm create hono@latest
Your terminal output should resemble the following.
aaronksaunders@Aarons-iMac LIVE % npm create hono@latest
Need to install the following packages:
create-hono@0.14.3
Ok to proceed? (y) y
> npx
> create-hono
create-hono version 0.14.3
? Target directory my-hono-1
? Which template do you want to use? nodejs
? Do you want to install project dependencies? yes
? Which package manager do you want to use? npm
✔ Cloning the template
✔ Installing project dependencies
🎉 Copied project files
Get started with: cd my-hono-1
The minimal code for the hono server is at index.ts
import { serve } from "@hono/node-server";
import { Hono } from "hono";
const app = new Hono();
app.get("/", (c) => {
return c.text("Hello Hono!");
});
// set port
const port = 3000;
console.log(`Server is running on http://localhost:${port}`);
// serve app
serve({
fetch: app.fetch,
port,
});
Now to test the build, change to directory and run the command below.
npm run dev
The server should be running on localhost:3000
if you access it in a web browser, you should receive a response from the server.
Hello Hono!
Added Drizzle and SQLite
Useful links
Execute the following command in the terminal
npm i drizzle-orm better-sqlite3 dotenv
npm i -D drizzle-kit tsx
- better-sqlite-3 is the sqlite version we use in our application – dotenv is used to read environment files
- drizzle-kit is a set of utilities that support drizzle orm integration
create .env
document
DATABASE_URL=./db.sqlite
Create a drizzle directory, which is the location where the migration files will be generated.
create /src/db/schema.ts
and add the following information
import { sql } from "drizzle-orm";
import { int, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
export const usersTable = sqliteTable(
"users_table",
{
id: int().primaryKey({ autoIncrement: true }),
name: text().notNull(),
age: int().notNull(),
email: text().notNull().unique(),
createdAt: text()
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
updatedAt: text()
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
},
(table) => [uniqueIndex("email_idx").on(table.email)]
);
export type User = typeof usersTable.$inferSelect;
export type InsertUser = typeof usersTable.$inferInsert;
We are building a table and exporting some types that can be used when interacting with the output of a query or constructing objects that need to be queried.
create /src/db/index.ts
Used to manage database execution instances created by drizzle orm.
// src/db/index.ts
import { drizzle } from "drizzle-orm/better-sqlite3";
import Database from "better-sqlite3";
import * as schema from "./schema.js";
import "dotenv/config";
const sqlite = new Database(process.env.DATABASE_URL ?? "sqlite.db");
export const db = drizzle(sqlite, { schema });
create drizzle.config.ts
In the project root directory
import "dotenv/config";
import { defineConfig } from "drizzle-kit";
export default defineConfig({
out: "./drizzle",
schema: "./src/db/schema.ts",
dialect: "sqlite",
dbCredentials: {
url: process.env.DATABASE_URL!,
},
});
Add script to package.json
Generate migrations and apply them to the repository
"db:generate": "drizzle-kit generate",
"db:migrate": "drizzle-kit migrate"
Run the script to build the repository and push the migration. The terminal output should be similar to the following output.
aaronksaunders@Aarons-iMac my-hono-1 % npm run db:generate
> db:generate
> drizzle-kit generate
No config path provided, using default 'drizzle.config.ts'
Reading config file '/Users/aaronksaunders/dev/LIVE/my-hono-1/drizzle.config.ts'
1 tables
users_table 6 columns 2 indexes 0 fks
[✓] Your SQL migration file ➜ drizzle/0000_wakeful_greymalkin.sql 🚀
aaronksaunders@Aarons-iMac my-hono-1 % npm run db:migrate
> db:migrate
> drizzle-kit migrate
No config path provided, using default 'drizzle.config.ts'
Reading config file '/Users/aaronksaunders/dev/LIVE/my-hono-1/drizzle.config.ts'
[✓] migrations applied successfully!%
aaronksaunders@Aarons-iMac my-hono-1 %
Use drizzle kit studio to add some users to the database.
npx drizzle-kit studio
Add a new route to query users in the database
import { db } from "./db/index.js";
import { Hono } from "hono";
import { usersTable } from "./db/schema.js";
import { eq } from "drizzle-orm";
const usersRoute = new Hono();
// Get all users
usersRoute.get("/", async (c) => {
const allUsers = await db.query.usersTable.findMany();
return c.json(allUsers);
});
// Get a user by id, be sure to note the conversion of
// the id from string back to a number
usersRoute.get("/:id", async (c) => {
const { id } = c.req.param();
const userResp = await db.query.usersTable.findFirst({
where: eq(usersTable.id, Number(id)),
});
return c.json(userResp);
});
// Create a user
usersRoute.post("/", async (c) => {
const { name, email, age } = await c.req.json();
const newUserResp = await db.insert(usersTable).values({ name, email, age });
return c.json(newUserResp);
});
export default usersRoute;
Adjustment index.ts
Include a new set of routes
import { serve } from "@hono/node-server";
import { Hono } from "hono";
import usersRoute from "./users-route.js";
const app = new Hono();
app.get("/", (c) => {
return c.text("Hello Hono!");
});
// Use the users routes
app.route("/users", usersRoute);
const port = 3000;
console.log(`Server is running on http://localhost:${port}`);
serve({
fetch: app.fetch,
port,
});
Use tools like postman or thunderbolt VSCode Extension to test the API
source code
video