Skip to content

Instantly share code, notes, and snippets.

@SuperstrongBE
Created November 20, 2023 12:52
Show Gist options
  • Save SuperstrongBE/2d4e6d1aac89797270745f22c9ba047b to your computer and use it in GitHub Desktop.
Save SuperstrongBE/2d4e6d1aac89797270745f22c9ba047b to your computer and use it in GitHub Desktop.
Research around decorator and api route
import { NextResponse } from "next/server";
import { PostMethodSymbol } from "./http-methods/post";
import { GetMethodSymbol } from "./http-methods/get";
export interface APIService {
GET:()=>void,
POST:()=>void,
}
// How can i fix the return type to avoid type check issue ?
export function ApiService() {
return <T extends { new(...args: any[]): {} }>(constructor: T)=>{
return class extends constructor implements APIService {
constructor(...args:any[]) {
super(args)
}
POST(){
if (Reflect.hasMetadata(PostMethodSymbol, this)) {
const method = Reflect.getMetadata(PostMethodSymbol, this);
return method.value.apply(this);
} else {
return NextResponse.json({})
}
};
GET() {
console.log(this,'is undefined ?')
if (Reflect.hasMetadata(GetMethodSymbol, this)) {
const method = Reflect.getMetadata(GetMethodSymbol, this);
return method.value.apply(this);
} else {
return NextResponse.json({})
}
}
};
}
}
import { NextResponse } from "next/server";
import "reflect-metadata"
export const GetMethodSymbol = Symbol('GET_METHOD')
export function Get() {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = async () => {
const returnValue = await originalMethod.apply(target, ...arguments);
return NextResponse.json(returnValue)
}
Reflect.defineMetadata(GetMethodSymbol, descriptor, target);
return descriptor
};
}
import { NextResponse } from "next/server";
import "reflect-metadata"
export const PostMethodSymbol = Symbol('POST_KEY')
export function Post() {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = ()=>{
const returnValue = originalMethod.apply(target, ...arguments);
return NextResponse.json(returnValue)
}
Reflect.defineMetadata(PostMethodSymbol, descriptor, target);
return descriptor
};
}
import { APIService, ApiService, Get, Post } from '@futureshit/datasources';
@ApiService()
class TestService {
@Post()
doPost() {
}
@Get()
async doGet() {
return {from:'decorated inner route'}
}
}
// Currently ulgy fix
const t = new TestService();
export async function GET(){
return t.GET()
}
//prefered
// export const {GET, POST} from new TestService()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment