Skip to content

korbai/koa-autorouter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

7 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

koa-autorouter

Modern autorouter middleware for Koa.js v2+ with async/await support, based on folder/file hierarchy.

✨ Features

  • πŸš€ Modern: Full async/await support for Koa v2+
  • πŸ“ File-based routing: Routes automatically generated from directory structure
  • 🎯 Convention over configuration: Minimal setup, maximum productivity
  • πŸ”§ Flexible: Works with any template engine
  • πŸ“¦ TypeScript support: Full type definitions included
  • πŸ›‘οΈ Secure: Updated dependencies with security patches

πŸ”„ Migration from v1.x

v1.x (Generator functions):

exports.index = function *(next) {
  this.state.name = 'Server';
  yield this.view();
};

v2.x (Async/await):

exports.index = async function(ctx, next) {
  ctx.state.name = 'Modern Server';
  await ctx.view();
};

πŸ“¦ Installation

npm install koa-autorouter

πŸš€ Quick Start

app.js

const Koa = require('koa');
const path = require('path');
const views = require('koa-views');
const autorouter = require('koa-autorouter');

const app = new Koa();

// Setup template engine (example with Handlebars)
app.use(views(path.join(__dirname, 'views'), {
  extension: 'html',
  map: { html: 'handlebars' }
}));

// Setup autorouter
app.use(autorouter({
  root: path.join(__dirname, 'views/'),
  ext: '.html'
}));

app.listen(3000);

πŸ“ Directory Structure

views/
β”œβ”€β”€ index.js              # GET /
β”œβ”€β”€ index.html            # Template for /
β”œβ”€β”€ user/
β”‚   β”œβ”€β”€ profile.js        # GET /user/profile
β”‚   β”œβ”€β”€ profile.html      # Template
β”‚   └── settings.js       # GET /user/settings
β”œβ”€β”€ admin/
β”‚   β”œβ”€β”€ index.js          # GET /admin/
β”‚   β”œβ”€β”€ help.html         # GET /admin/help (standalone view)
β”‚   └── reports/
β”‚       └── daily.js      # GET /admin/reports/daily

🎯 Controller Patterns

Basic Controller

// views/user/index.js
exports.index = async function(ctx, next) {
  ctx.state.users = await getUsers();
  await ctx.view(); // Renders user/index.html
};

Full CRUD Controller

// views/posts/index.js

// Optional middleware for all actions
exports.middleware = async function(ctx, next) {
  ctx.state.currentUser = await getCurrentUser(ctx);
  await next();
};

// GET /posts
exports.index = async function(ctx) {
  ctx.state.posts = await Post.findAll();
  await ctx.view();
};

// POST /posts
exports.create = async function(ctx) {
  const post = await Post.create(ctx.request.body);
  ctx.redirect(`/posts/${post.id}`);
};

// GET /posts/:id
exports.select = async function(ctx) {
  const id = ctx.state.id; // Auto-populated from URL
  ctx.state.post = await Post.findById(id);
  await ctx.view();
};

// POST /posts/:id
exports.update = async function(ctx) {
  const id = ctx.state.id;
  await Post.update(id, ctx.request.body);
  ctx.redirect(`/posts/${id}`);
};

// GET /posts/:id/edit
exports.edit = async function(ctx) {
  const id = ctx.state.id;
  ctx.state.post = await Post.findById(id);
  await ctx.view();
};

// POST /posts/:id/edit
exports.save = async function(ctx) {
  const id = ctx.state.id;
  await Post.update(id, ctx.request.body);
  ctx.redirect(`/posts/${id}`);
};

// GET /posts/:id/delete
exports.delete = async function(ctx) {
  const id = ctx.state.id;
  await Post.delete(id);
  ctx.redirect('/posts');
};

βš™οΈ Configuration Options

app.use(autorouter({
  root: path.join(__dirname, 'views/'),  // Controllers directory
  ext: '.html',                          // Template extension
  enableStandalone: true                 // Enable views without controllers
}));

πŸ”§ Template Engine Integration

With Handlebars

const views = require('koa-views');
app.use(views('views', { extension: 'hbs', map: { hbs: 'handlebars' } }));

With Pug

const views = require('koa-views');
app.use(views('views', { extension: 'pug' }));

With EJS

const views = require('koa-views');
app.use(views('views', { extension: 'ejs' }));

πŸ›£οΈ Route Mapping

File Path URL HTTP Method
views/index.js β†’ exports.index GET / GET
views/user/profile.js β†’ exports.index GET /user/profile GET
views/posts/index.js β†’ exports.create POST /posts POST
views/posts/index.js β†’ exports.select GET /posts/:id GET
views/admin/help.html GET /admin/help GET (standalone)

πŸ§ͺ Testing

Run the example:

cd example
npm install
npm start

Visit:

πŸ” TypeScript Support

import autorouter from 'koa-autorouter';
import { Context } from 'koa';

// Controller with types
export const index = async (ctx: Context) => {
  ctx.state.message = 'Hello TypeScript!';
  await ctx.view();
};

πŸ†š Comparison with Other Solutions

Feature koa-autorouter v2 Next.js Nuxt.js
Framework Koa.js React Vue.js
File-based routing βœ… βœ… βœ…
Server-side only βœ… ❌ ❌
Lightweight βœ… ❌ ❌
Template agnostic βœ… ❌ ❌

πŸ”„ Breaking Changes from v1.x

  1. Koa version: Requires Koa v2+ (Node.js 14+)
  2. Function signatures: function*(ctx, next) β†’ async function(ctx, next)
  3. Context: this β†’ ctx parameter
  4. Async: yield β†’ await
  5. Dependencies: Removed lodash, co-fs dependencies

πŸ“„ License

MIT

🀝 Contributing

  1. Fork the repository
  2. Create your feature branch
  3. Add tests for new features
  4. Ensure all tests pass
  5. Submit a pull request

Upgrade your Koa routing to the modern era! πŸš€

About

Simple autorouter middleware

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •