# Controller

# Introduction

Instead of defining all of your request handling logic as closures in your route files, you can organize this behavior using "controller" classes. Controllers can group related request handling logic into a single class. For example, a UserController class might handle all incoming requests related to users, including showing, creating, updating, and deleting users. By default, controllers are stored in the App/Http/Controllers directory.

# Creating Controllers

# Basic Controllers

Let's take a look at an example of a basic controller. To create a new controller called UserController, use the maker command for controller:

ts-node maker make-controller UserController

We will have:

"use strict";
import { Request, Response, NextFunction } from "Elucidate/HttpContext";
import HttpResponse from "Elucidate/HttpContext/ResponseType";

class UserController {
  //
}
export default UserController;

Let's add some basic feature to our UserController

import UserModel from "App/Model/User_model";
import { Request, Response, NextFunction } from "Elucidate/HttpContext";
import HttpResponse from "Elucidate/HttpContext/ResponseType";

("use strict");
class UserController {
  show = async (req: Request, res: Response) => {
    let id = req.params.id;
    let user = await UserModel.query().findById(id);
    return HttpResponse.OK(res, user);
  };
}
export default UserController;

You can define a route to this controller method like so:

Route.get("/user/:id", "UserController@show");

# Controllers & Paths

It is important to note that we did not specify the full controller path when defining the controller route. Since the RouteServiceProvider loads your route files within a route group that contains the paths, we only specified the portion of the class name that comes after the App/Http/Controllers portion of the path.

If you choose to nest your controllers deeper into the App/Http/Controllers directory, use the specific class name relative to the App/Http/Controllers root path. So, if your full controller class is App/Http/Controllers/Employee/AdminController, you should register routes to the controller like so:

Route.get("/employee", "Employee/AdminController@method");

# Resource Controllers

ExpressWebJs resource routing assigns the typical "CRUD" routes to a controller with a single line of code. For example, you may wish to create a controller that handles all HTTP requests for "users" stored by your application. Using the make-controller Maker command, we can quickly create such a controller:

ts-node maker make-controller UserController -r

This command will generate a controller at App/Http/Controllers/UserController.ts. The controller will contain a method for each of the available resource operations.

"use strict";
import { Request, Response, NextFunction } from "Elucidate/HttpContext";
import HttpResponse from "Elucidate/HttpContext/ResponseType";

class UserController {
  /**
   * Display a listing of the resource.
   * @method
   * @endpoint
   * @param Request
   * @return Response
   */
  index = async (req: Request, res: Response) => {
    throw new Error("UserController index method not implemented.");
  };

  /**
   * Store a newly created resource in storage.
   * @method
   * @endpoint
   * @param Request
   * @return Response
   */
  store = async (req: Request, res: Response) => {
    throw new Error("UserController store method not implemented.");
  };

  /**
   * Display the specified resource.
   * @method
   * @endpoint
   * @param Request
   * @return Response
   */
  show = async (req: Request, res: Response) => {
    throw new Error("UserController show method not implemented.");
  };

  /**
   * Update the specified resource in storage.
   * @method
   * @endpoint
   * @param Request
   * @return Response
   */
  update = async (req: Request, res: Response) => {
    throw new Error("UserController update method not implemented.");
  };

  /**
   * Remove the specified resource from storage.
   * @method
   * @endpoint
   * @param Request
   * @return Response
   */
  destroy = async (req: Request, res: Response) => {
    throw new Error("UserController destroy method not implemented.");
  };
}

export default UserController;

# Dependency Injection & Controllers

ExpressWebJs service container is used to resolve all ExpressWebJs controllers. As a result, you are able to type-hint any dependencies you've registered in the App/Providers/AppServiceProvider.ts register method into your controller constructor. The declared dependencies will automatically be resolved and injected into the controller instance:

First register your service in App/Providers/AppServiceProvider.ts register method:

import ServiceProvider from "Elucidate/Support/ServiceProvider";
import { MyService } from "App/Service/MyService";

export class MyServiceProvider extends ServiceProvider {
  /**
   * Register application services.
   * @return void
   */
  register() {
    this.singleton(MyService);
  }
}

We can now inject MyService into our UserController constructor:

import IMyService from "App/Service/MyService";

export class UserController {
  protected myService: IMyService;

  constructor(MyService: IMyService) {
    this.myService = MyService;
  }
}