The backend of this project is built using the Hono framework for API routes, SQLite via Val Town's std/sqlite module for data persistence, and OAuth middleware for authentication.
BACKEND/ ├── README.md # This file ├── routes.users.ts # Hono API routes for user operations └── storage.users.ts # SQLite database operations for users
To maintain consistency and clarity across the backend codebase, follow these naming conventions:
Route files should follow the pattern:
routes.{resource}.ts
Examples:
routes.users.ts- User-related API endpointsroutes.posts.ts- Post-related API endpointsroutes.comments.ts- Comment-related API endpoints
Storage files (database operations) should follow the pattern:
storage.{resource}.ts
Examples:
storage.users.ts- User database operationsstorage.posts.ts- Post database operationsstorage.comments.ts- Comment database operations
Purpose: Hono API routes for user operations.
Key Features:
- Exports a Hono router instance
- Provides the
/userendpoint (GET) to retrieve current user information - Integrates with OAuth middleware for authentication
- Uses
storage.users.tsfor database operations
Endpoints:
| Method | Path | Description | Auth Required |
|---|---|---|---|
| GET | /user | Get current user info | Yes |
Example Response:
{ "user": { "id": 1, "email": "user@example.com", "username": "johndoe", "profile_image_url": "https://example.com/avatar.jpg" } }
Purpose: SQLite database operations for user management.
Key Features:
- Manages the
users_v1table (configured inshared/config.js) - Provides functions for creating and retrieving user records
- Automatically creates the users table if it doesn't exist
- Uses Val Town's
std/sqlitemodule
Exported Functions:
| Function | Description | Parameters | Returns |
|---|---|---|---|
getOrCreateUser | Retrieves an existing user by email or creates a new one | email, username?, profileImageUrl? | Promise<User> |
User Schema:
| Column | Type | Constraints |
|---|---|---|
id | INTEGER | PRIMARY KEY AUTOINCREMENT |
email | TEXT | UNIQUE NOT NULL |
username | TEXT | Optional |
profile_image_url | TEXT | Optional |
created_at | TEXT | DEFAULT CURRENT_TIMESTAMP |
updated_at | TEXT | DEFAULT CURRENT_TIMESTAMP |
Type Definition: See shared/types.ts for the User interface.
Hono is a lightweight, fast web framework for building API routes. It provides:
- Expressive routing
- Middleware support
- TypeScript support
- Minimal overhead
Val Town provides a hosted SQLite service via https://esm.town/v/std/sqlite/main.ts:
- Serverless-compatible
- Persistent storage across requests
- Simple SQL execution interface
Authentication is handled by Val Town's OAuth middleware (https://esm.town/v/std/oauth/middleware.ts):
- Automatically handles
/auth/loginand/auth/logoutroutes - Provides
getOAuthUserData()to retrieve session information - Integrates seamlessly with Val Town's authentication system
When adding a new resource to the backend:
-
Create the storage file:
- Name it
storage.{resource}.ts - Define the database schema
- Export functions for CRUD operations
- Name it
-
Create the routes file:
- Name it
routes.{resource}.ts - Import the storage functions
- Define API endpoints using Hono
- Export the router
- Name it
-
Update the main app:
- Import the new router in
app.http.ts - Mount it under the
/apiprefix
- Import the new router in
-
Add types (if needed):
- Update
shared/types.tswith new interfaces
- Update
-
Update configuration (if needed):
- Add table names to
shared/config.js
- Add table names to
- Table versioning: When modifying a table schema, create a new version (e.g.,
users_v2) rather than altering the existing table - Error handling: Let errors bubble up rather than catching and logging them; Hono's error handler will provide full stack traces
- Type safety: Always use TypeScript interfaces for data structures
- Authentication: Use
getOAuthUserData()to check authentication status in protected routes - Environment variables: Use
Deno.env.get()for secrets, though prefer APIs that don't require keys when possible