Skip to content

Instantly share code, notes, and snippets.

@anishdcruz
Last active September 15, 2024 19:29
Show Gist options
  • Save anishdcruz/e6b520abeedb9b8ed26535197c148ebc to your computer and use it in GitHub Desktop.
Save anishdcruz/e6b520abeedb9b8ed26535197c148ebc to your computer and use it in GitHub Desktop.
Adonisjs file based routing
// create file api/posts/:id.ts
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export const POST = async({params}: HttpContextContract) => `Viewing post with id ${params.id}`
export const PUT = async({params}: HttpContextContract) => `Viewing put with id ${params.id}`
export const GET = async({params}: HttpContextContract) => `Viewing put with id ${params.id}`
import { ApplicationContract } from '@ioc:Adonis/Core/Application'
import path from 'path'
import fs from 'fs'
const extensions = ['.ts']
enum HTTPMethod {
GET = 'get',
POST = 'post',
PUT = 'put',
DELETE = 'delete'
}
const isRoute = (ext: string) => extensions.includes(ext)
const isTest = (name: string) => name.endsWith('.test') || name.endsWith('.spec');
const isDeclaration = (name: string, ext: string) => ext === '.ts' && name.endsWith('.d');
const addRequestHandler = (
module,
method: HTTPMethod,
route,
fileRouteServerPath: string,
) => {
const handler = method === 'get'
? module.default || module[method.toUpperCase()]
: module[method.toUpperCase()]
if(handler) {
route[method](fileRouteServerPath, handler)
console.debug(`${method.toUpperCase()} ${fileRouteServerPath}`)
}
}
const registerRoutes = async (route, folder: string, pathPrefix = '') => {
fs.readdirSync(folder, { withFileTypes: true })
.forEach((folderOrFile) => {
const currentPath = path.join(folder, folderOrFile.name)
const routeServerPath = `${pathPrefix}/${folderOrFile.name.replace('[', ':').replace(']', '')}`
if (folderOrFile.isDirectory()) {
registerRoutes(route, currentPath, routeServerPath)
} else if (folderOrFile.isFile()) {
const { ext, name } = path.parse(folderOrFile.name);
if (!isRoute(ext) || isTest(name) || isDeclaration(name, ext)) {
return
}
let fileRouteServerPath = pathPrefix;
if (name !== 'index') {
fileRouteServerPath += '/' + name.replace('[', ':').replace(/\]?$/, '')
}
if (fileRouteServerPath.length === 0) {
fileRouteServerPath = '/'
}
const module = require(currentPath)
Object.values(HTTPMethod).forEach((method) => {
addRequestHandler(module, method, route, fileRouteServerPath)
})
}
})
}
export default class AppProvider {
constructor (protected app: ApplicationContract) {
}
public register () {
// Register your own bindings
}
public async boot () {
// IoC container is ready
const route = this.app.container.use('Adonis/Core/Route')
// all ts files within api will be registered
await registerRoutes(route, path.join(__dirname, '..', './api'))
}
public async ready () {
// App is ready
}
public async shutdown () {
// Cleanup, since app is going down
}
}
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export const GET = async(ctx: HttpContextContract) => `Viewing index`
// create file api/posts/index.ts
// also can use export default for get method
export default () => 'Hello Posts'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment