question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add subrouter functionality

See original GitHub issue

Initially I wanted to disallow this entirely (avoid Express nesting nightmare), and while I still mostly lean in that direction, there are valid use cases where the DX is better to have a “subrouter” than to split routing/behavior logic across two locations. (Thanks @evanderkoogh for raising this!)

Suppose you wanted to require Authentication header validation for all /admin/* routes:

Before

AKA current

// src/index.js
import * as CORS from 'worktop/cors';
import * as Cache from 'worktop/cache';
import { Router, compose } from 'worktop';
import * as Projects from './routes/projects';
import * as Auth from './utils/auth';

const API = new Router;

API.prepare = compose(
  // Apply CORS globally
  CORS.preflight,
  // Validate Auth if "/admin/*" route
  async (req, res) => {
    if (req.pathname.startsWith('/admin/') {
      // assume this is Promise<Response | void>
      return Auth.validate(req, res);
    }
  }
);

// The actual administrative actions
// > Authentication & Authorization handled above
API.add('GET', '/admin/projects', Projects.list);
API.add('POST', '/admin/projects', Projects.create);

Cache.listen(API.run);

After

// src/routes/admin.js
import { Router } from 'worktop';
import * as Auth from '../utils/auth';
import * as Projects from './projects';

// NOTE: Exported!
export const Admin = new Router;

// All routes in this Router must 
// have valid Authentication header
Admin.prepare = Auth.validate;

API.add('GET', '/projects', Projects.list);
API.add('POST', '/projects', Projects.create);


// src/index.js
import { Router } from 'worktop';
import * as CORS from 'worktop/cors';
import * as Cache from 'worktop/cache';
import { Admin } from './routes/admin';

const API = new Router;

// Apply CORS globally
API.prepare = CORS.preflight;

// NEW – direct all "/admin/*" routes to Admin router
API.attach('/admin', Admin);

Cache.listen(API.run);

The important thing to note here is that the API.attach method (in the last snippet) is the new proposed method. I’m also considering “mount” as the method name… or “direct” lol. I’m purposefully avoiding .all() and .use() here, since they’re loaded terms – more on that below.

Relatedly, this means that all /admin/* routes must be handled by the Admin router. In other words, doing something like this will fail/never hit the foo or the bar handlers.

// I WILL NEVER RUN
API.add('GET', '/admin/foo', foo);

// attach subrouter
API.attach('/admin', Admin);

// NEITHER WILL I
API.add('GET', '/admin/bar', bar);

This may seem counterintuitive for Node.js users (especially Express users) since they may be used to the stacking-router model. In worktop, every route points to a single handler – handler/middleware functions can be composed into a final handler, but it’s still a single handler. This new method name needs to double-down on/imply this distinction. Calling this all() or use() would be cause confusion since, coming from Express land, those imply that you’re attaching items that expect to work alongside / in conjunction with other handlers. This isn’t the case here – it’s a complete detour.

Open to feedback & suggestions!

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:6
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
lukeedcommented, Sep 27, 2021

Closed by #96 and now available in worktop@next. Will be included in the next 0.8.0 stable release.

1reaction
lukeedcommented, Sep 23, 2021

It will be mount. And it’s coming in an upcoming @next release, which means it’ll be part of 0.8

Read more comments on GitHub >

github_iconTop Results From Across the Web

Proper way of creating a subrouter · Issue #494 · go-chi/chi
What's the best way to achieve this functionality (creating a subrouter while inheriting middleware from parent router) with Chi?
Read more >
Set gorilla mux subrouter - Stack Overflow
I would like to set the subrouter to an existing router. Like: r.PathPrefix("/api").SetSubrouter(api.GetRouter()) //won't work.
Read more >
Access devices "inside" subrouter - Super User
Add a static route from Router to Sub-Router for 192.168.16.0/24. Sub-Router already knows how to get to Router because of DHCP. The specific ......
Read more >
Bigger Applications - Multiple Files - FastAPI
And we can add a list of dependencies that will be added to all the path operations in the router and will be...
Read more >
mux, middleware, and subrouters - Google Groups
I've been struggling to write straightforward code when using subrouters and/or ... Is there a strong argument against adding this functionality to mux...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found