controller

Creator: coderz1093

Last updated:

0 purchases

controller Image
controller Images

Languages

Categories

Add to Cart

Description:

controller

Controller #
Controller is a library that facilitates writing HTTP request handlers with Shelf.
Features #

Request mapping
Validation
Security

Getting started #
Add the controller libraries to pubspec.yaml:
dependencies:
controller: ^0.1.10+1
json_annotation: ^4.8.0

dev_dependencies:
build_runner: ^2.3.3
controller_generator: ^0.1.8
json_serializable: ^6.6.1
copied to clipboard
Usage #
Controller #

Add the @controller metadata to the class where you want to handle requests.
Annotate handler methods with HTTP verbs (@Get, @Put, @Delete, ...).
Use @body to deserialize a JSON body to an object.
Prefix path parameters with a colon.

import 'package:controller/controller.dart';
import 'package:shelf/shelf.dart';

part 'todo_controller.g.dart';

@controller
class TodoController {
@Post('/todos')
Future<Response> addTodo(@body Todo todo) {
// implementation goes here
}

@Get('/todos/:id')
Future<Response> getTodo(String id) {
// implementation goes here
}
}
copied to clipboard
Request body #

Annotate classes mapped to the request body with @validatable.
Annotate fields with validator metadata.
Add a fromJson() factory method.

import 'package:controller/controller.dart';
import 'package:json_annotation/json_annotation.dart';

part 'todo.g.dart';

@validatable
@JsonSerializable(createToJson: false)
class Todo {
@notEmpty
final String id;
@notEmpty
final String description;

Todo({
required this.id,
required this.description,
});

factory Todo.fromJson(Map<String, dynamic> json) => _$TodoFromJson(json);
}
copied to clipboard
Validation #

Validation metadata can be added on request bodies and controller parameters
Out-of-the-box available validators include:

@Min(value) and @Max(value)
@Length(min, max)
@notEmpty
@Regex(pattern, description)
@Unique(existsPredicate)



Returning responses #

You can return Shelf Response objects.
When returning an object with a toJson method, a 200 OK response is returned with the JSON as body.

import 'package:controller/controller.dart';
import 'package:shelf/shelf.dart';
import 'package:json_annotation/json_annotation.dart';

part 'todo_controller.g.dart';

@controller
class TodoController {
@Post('/todos')
// Returning Future<void> will return an empty `200 OK` response.
Future<void> addTodo(@body Todo todo) {
// implementation goes here
}

@Get('/todos/:id')
// Returning Future<A> will call `A.toJson()` and return a `200 OK` response
// with the JSON in the body.
Future<Todo> getTodo(String id) {
// implementation goes here
}
}

@JsonSerializable()
class Todo {
@notEmpty
final String id;
@notEmpty
final String description;

Todo({
required this.id,
required this.description,
});

factory Todo.fromJson(Map<String, dynamic> json) => _$TodoFromJson(json);

Map<String, dynamic> toJson() => _$TodoToJson(this);
}
copied to clipboard
Securing requests #

Add a @Secured metadata to the endpoints you want to protect with security.
@Secured takes a parameter with a condition the request has to comply with.
You can either use off the shelf conditions or write your own.

import 'package:controller/controller.dart';
import 'package:shelf/shelf.dart';

part 'todo_controller.g.dart';

@controller
class TodoController {
@Post('/todos')
// Check whether the user has a claim "role" with value "todo-editor"
@Secured(HasClaim('role', 'todo-editor'))
Future<Response> addTodo(@body Todo todo) {
// implementation goes here
}

@Get('/todos/:id')
// Custom condition defined below
@Secured(IsTodoOwner())
Future<Response> getTodo(String id) {
// implementation goes here
}
}

class IsTodoOwner extends SecurityCondition {
const IsTodoOwner();

@override
Future<bool> evaluate(Map<String, dynamic> claims, // the claims found in the token or user database
Map<String, String> headers, // request headers and parameters
) async {
final userId = claims['userId'];
// When true, the user is allowed to access the endpoint
return userId != null && headers['id'].startsWith(userId);
}
}
copied to clipboard
Setting up the server #
Run dart run build_runner build to generate dispatcher builders and validators.
Create the request dispatcher with the generated dispatcher builders and wire it in Shelf:
import 'package:controller/controller.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart';
import 'todo/todo_controller.dart';

void main() async {
final todoController = TodoController();

// Only required when you have secured controllers
final security = JwtSecurity(
issuerUri: Uri.parse('https://issuer.uri.goes.here'),
clientId: 'your-applications-client-id',
);

final dispatcher = createRequestDispatcher([
// Only controllers with @Secured methods will take the security parameter
TodoController$DispatcherBuilder(todoController, security),
]);
final handler = Pipeline().addHandler(dispatcher);
final server = await serve(handler, '0.0.0.0', 8080);
}
copied to clipboard

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Files In This Product:

Customer Reviews

There are no reviews.