Skip to main content

Controllers

Introduction

Instead of defining all of your request handling logic as anonymous functions in route files, you may wish to organize this behavior using Controller classes. Controllers can group related request handling logic into a single class. Controllers are stored in the app/Http/Controllers directory.

Basic Controllers

Defining Controllers

To create a new controller, use the make:controller Craftsman command:

node craftsman make:controller UserController

This command will place a new UserController class within your app/Http/Controllers directory.

Below is an example of a basic controller class. Note that the controller extends the base controller class included with Formidable:

app/Http/Controllers/UserController.ts
import { DB } from '@formidablejs/framework'
import { Request } from '@formidablejs/framework'
import { NotFoundException } from '@formidablejs/framework'
import { Controller } from './Controller'

export class UserController extends Controller {
async show(request: Request): Promise<object> {
const user = await DB.table('users').where('id', request.param('id')).first()

if (!user) {
throw new NotFoundException('User does not exist')
}

return user
}
}

You can define a route to this controller action like this:

routes/api.ts
import { Route } from '@formidablejs/framework'
import { UserController } from '../app/Http/Controllers/UserController'

Route.get('/user/:id', [UserController, 'show'])

Now, when a request matches the specified route URI, the show method in the UserController class will be executed.

Helpers

The base Controller class comes with helper functions.

notFound

The notFound function throws a 404 Exception:

...
export class UserController extends Controller {
async show(request: Request): Promise<any> {
if ((await DB.table('users').where('id', request.param('id')).count())[0]["count(*)"] < 1) {
this.notFound()
}

...

You may also pass a custom error message:

...
export class UserController extends Controller {
async show(request: Request): Promise<any> {
if ((await DB.table('users').where('id', request.param('id')).count())[0]["count(*)"] < 1) {
this.notFound('User does not exist')
}

...

badRequest

The badRequest function throws a 400 Exception:

...
export class UserController extends Controller {
destroy(request: Request): any {
if (!request.auth().can('users:delete')) {
this.badRequest()
}

...

And with a custom message:

...
export class UserController extends Controller {
destroy(request: Request): any {
if (!request.auth().can('users:delete')) {
this.badRequest('Permission denied')
}

...

validate

The validate function makes it easier to validate incoming requests:

...
export class UserController extends Controller
update(request: Request): any {
const validator = validate(request, {
name: 'required',
email: 'required|email'
})

if (validator.fails()) {
throw ValidationException.withMessage(validator.errors.errors)

...