JCC Express

Controllers

Introduction

Controllers group HTTP actions as class methods. Routes point at them with array syntax: [ControllerClass, "methodName"] (see Routing.md). The framework resolves the controller from the service container, then invokes the action—either with constructor injection (@Inject on the class and typed constructor parameters) or method injection (@Method on the action and typed parameters, optional route-param mapping, models, form requests, and httpContext defaults).

Enable experimentalDecorators and emitDecoratorMetadata in TypeScript so parameter types are available for reflection.


Class decorator: @Inject()

@Inject() is a class-level decorator. Apply it to any controller the container should treat as part of the dependency-injection story (alongside constructor type hints).

TypeScript

When a route runs, the framework makes the controller. The container reads design:paramtypes on the constructor and resolves each dependency by type (or name where configured). Register those services in a provider or the container before the controller is used.


Method decorator: @Method()

@Method() is a method-level decorator. It registers metadata so callControllerMethod can build the argument list from the container, route parameters, and the current request.

Without @Method(), an action invoked through the router is called as action({ req, res, next }) only—the older single-argument style. With @Method(), each parameter is resolved according to its type and options.

Import:

TypeScript

Mapping route parameters to primitives

For parameters typed as string or number, you can tie them to req.params by name using params on @Method. The array is consumed in parameter order; only non-model, non-FormRequest slots advance the params index (see jcc-express-mvc/lib/Dependency/index.ts).

TypeScript

Match the route to those names, for example:

TypeScript

id and name are taken from req.params; string values are passed through, numeric-looking strings may be coerced when the parameter type is Number in the metadata pipeline.


Method injection without params

Omit params when arguments are only services, models, FormRequest subclasses, or context defaults:

  • Service types — resolved from the container (this.resolve(dep.type)).
  • Model subclasses (prototype extends framework Model) — route model binding from req.params (see Routing.md).
  • FormRequest subclasses — constructed with the current req, with rules() run before the action (details in Request.md).
  • Plain Object (as emitted for some patterns) — receives { req, res, next } for Express context.

Combine them in one signature in any order the resolver supports; use httpContext only in parameter defaults, not with const inside the body (see Routing.md).

TypeScript

Summary

  • @Inject() — class decorator; use with a constructor whose parameters are container dependencies.
  • @Method() — method decorator; enables per-action dependency injection instead of only { req, res, next }.
  • @Method({ params: ["id", "name"] }) — maps successive string / number parameters to those req.params keys, in order.

Keep actions focused; push heavy logic into services you inject in the constructor or method parameters.