Skip to main content

Controller

A @Controller() in Vaden defines a class that handles HTTP routes. It's one of the core building blocks of the framework.

The value passed to @Controller('/path') defines a route prefix applied to all methods in that class. For example:

('/users')
class UserController {
('/all')
String getAll() => 'Listing all users';
}

This will map to /users/all in the HTTP server.
Grouping routes with a common prefix helps keep your application modular and organized.

('/hello')
class HelloController {
final HelloService helloService;

helloController(this.helloService);

('/ping')
Response ping() => Response.ok(helloService.ping());
}
  • The base path /hello applies to all methods inside.
  • Constructor injection automatically injects HelloService if it’s registered.

Return Types

Controller methods in Vaden support multiple return types. Vaden will automatically adapt the response depending on what you return:

  • Response or Future<Response> → Used directly.
  • String or List<int> → Sent as plain body.
  • An object marked with @DTO() → Serialized to JSON.
  • A list of @DTO() → Serialized as a JSON array.
('/text')
String hello() => 'Hello World';

('/json')
UserDTO getUser() => UserDTO('admin');

('/list')
List<UserDTO> getUsers() => [UserDTO('a'), UserDTO('b')];

('/custom')
Future<Response> advanced() async => Response.ok('Manual');

HTTP Method Handlers

Vaden supports the following method decorators:

  • @Get()
  • @Post()
  • @Put()
  • @Delete()
  • @Head()
  • @Options()

@Param and @Query

These decorators extract data from the URL path or query string.

// http://localhost:8080/user/2
('/user/<id>')
String getUser(('id') int id) => 'User $id';

// http://localhost:8080/search?term=Text
('/search')
String search(('term') String term) => 'Searching $term';

You can omit the parameter name in the annotation:

('/product/<id>')
String getProduct(() String id) => 'Product $id';

In this case, the name of the variable (id) will be used as the key.

Both @Param and @Query support the following types:

  • String
  • int
  • double
  • bool

If a parameter is optional, you can declare it with a nullable type:

('/search')
Response search(('term') String? term) => ...;

This tells Vaden not to throw an error if the value is missing.

Using @Body with DTOs

The @Body() decorator binds the request JSON body to a Dart object. Only classes annotated with @DTO() are allowed:

()
class Credentials {
final String username;
final String password;
Credentials(this.username, this.password);
}

...

('/login')
String login(() Credentials credentials) => credentials.username;

Internally, Vaden uses the DSON engine to convert the request body into your DTO.

Wildcard Routing

Use @Mount() for wildcard endpoints — useful for advanced cases like WebSockets or proxy handlers:

('/socket')
class SocketController {
('/chat')
Response handle(Request request) {
return websocketHandler(request);
}
}