npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

nextjs-alternative-router

v0.0.1

Published

Alternative syntax for route.ts that combine multiple endpoints with TypeScript decorators. Inspired by NestJS controller syntax.

Downloads

5

Readme

nextjs-alternative-router (WIP)

Alternative syntax for route.ts that combine multiple endpoints with TypeScript decorators. Inspired by NestJS controller syntax.

npm i nextjs-alternative-router

Warning

The project does not have unit tests which means it's supposed to be used for experimental purposes only, but not for production apps. I'm going to add them in case if the idea actually looks interesting to other developers. For now it's just a personal project that I can install with NPM instead of copy-pasting the file every time. Give it a star if you want me to take this project more seriously.

Also worthy to mention that the router doesn't support dynamoc routes yet (foo/:id/bar) and you need to use query parameters instead.


Let's say tou have the following endpoints (an example from a real project).

  • /api/users
  • /api/users/me
  • /api/chat-sessions
  • /api/chat-sessions/chat-messages

Your regular file structure is going to look like that:

/users
  /route.ts
  /me
    /route.ts
/chat-sessions
  /route.ts
  /chat-messages
    /route.ts

With this library you need only 2 files:

/users/[[...]]/route.ts
/chat-sessions/[[...]]/route.ts

[[...]] folder name used for Dynamic Routes with empty segment name.

API

The library provides a function called createRouter that returns an object that contains NextJS route functions (GET, POST, PUT, DELETE) and decorators (get, post, put, del). The route handlers are going to be defined as a class with static methods (dev note: static method decorators are more flexible because they have access to the decorator's target).

import { createRouter } from 'nextjs-alternative-router';

const { get, post, GET, POST } = createRouter();

export class Route {
  @get()
  static getAllUsers = (req: NextRequest) => { /* ... */ };

  @get('/me')
  static getMe = (req: NextRequest) => { /* ... */ };

  @post()
  static createUser = (req: NextRequest) => { /* ... */ }
}

export { GET, POST };

The route handlers need to return an object instead of NextResponse.json.

// ...
@get()
static helloWorld = () => {
  return { hello: 'world' };
}
// ...

The library also provides HttpException (as well as helpful enum HttpStatus) that you can throw at your route handler and the library will make the route return proper error and status.

// ...
@get()
static helloWorld = () => {
  if(somethingWrong) {
    throw HttpException(HttpStatus.BAD_REQUEST, 'Something is wrong')
  }

  return { hello: 'world' };
}
// ...

Custom decorator

There is an example of a custom decorator that checks if user is authorised. checkAuth needs to be implemented based on how authorisation works in your app.

import { NextResponse, NextRequest } from 'next/server';
import { checkAuth } from './checkAuth';

export default function authGuard<T>() {
  return function (target: T, propertyKey: keyof T) {
    const originalMethod = target[propertyKey];
    if (typeof originalMethod === 'function') {
      // @ts-expect-error
      target[propertyKey] = async function (req: NextRequest, context?: any) {
        if (!req) return new NextResponse('req is not given at authGuard', { status: 401 });
        if (!(await checkAuth(req))) return new NextResponse('Unauthorised', { status: 401 });
        // eslint-disable-next-line @typescript-eslint/no-unsafe-return
        return originalMethod.call(target, req, context);
      };
    }
  };
}

// ...
@get()
authGuard() // use it after HTTP method decorator
static helloWorld = (req: YourCustomReq) => { // you may want to add some extra properties to req (current user for example) at checkAuth
  return { hello: 'world' };
}
// ...