Public
Like
expressweb
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
This project demonstrates how to adapt familiar Express.js and Mongoose patterns to work in Val Town's Deno environment using Hono and SQLite.
The project follows Express/Mongoose conventions but uses Val Town's stack:
- Express → Hono: Web framework for routing and middleware
- MongoDB/Mongoose → SQLite: Database with ORM-like patterns
- Node.js → Deno: Runtime environment
├── index.ts # Main app (like Express app.js)
├── models/
│ └── User.ts # User model (Mongoose-style patterns)
├── controllers/
│ └── userController.ts # Route handlers (Express controller style)
├── routes/
│ └── userRoutes.ts # Route definitions (Express router style)
├── middleware/
│ └── errorHandler.ts # Error handling middleware
└── README.md
GET /api/users/:id
Response:
{ "success": true, "data": { "id": 1, "name": "John Doe", "email": "john@example.com", "createdAt": "2024-01-01T00:00:00.000Z", "updatedAt": "2024-01-01T00:00:00.000Z" } }
GET /api/users
POST /api/users
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com"
}
PUT /api/users/:id
Content-Type: application/json
{
"name": "Jane Doe",
"email": "jane@example.com"
}
DELETE /api/users/:id
UserModel.findById()- Similar to MongooseUser.findById()UserModel.create()- Similar to MongooseUser.create()UserModel.findByIdAndUpdate()- Similar to Mongoose method- Static methods instead of instance methods
- Same controller pattern with error handling
- JSON responses with consistent structure
- HTTP status codes and error messages
- Similar route definition syntax
- Middleware support
- Parameter extraction with
c.req.param()
- Error handling middleware
- Request logging (similar to Morgan)
- Async middleware support
- Get user by ID:
curl https://your-val.web.val.run/api/users/1
- Create a new user:
curl -X POST https://your-val.web.val.run/api/users \ -H "Content-Type: application/json" \ -d '{"name": "John Doe", "email": "john@example.com"}'
- Get all users:
curl https://your-val.web.val.run/api/users
The API includes comprehensive error handling:
- 400: Bad Request (invalid parameters)
- 404: Not Found (user doesn't exist)
- 409: Conflict (email already exists)
- 500: Internal Server Error
- Database is automatically initialized on startup
- SQLite table is created if it doesn't exist
- All responses follow a consistent JSON structure
- Proper TypeScript typing throughout
- Error logging for debugging