Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enchant: Class-Based Middlewares and Endpoint callback #95

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

NathanDraco22
Copy link
Contributor

Thanks for this amazing idea!
Inspired by this Issue : #88

With this Mixin we can create class-based middlewares

class _ExampleMiddleware with CallableRequestMixin{
  @override
  FutureOr call(HttpRequest req, HttpResponse res) {
    if (req.headers.value('Authorization') != 'apikey') {
      throw AlfredException(401, {'message': 'authentication failed'});
    }
  }
}

void main() async {
  final app = Alfred();
  app.all('/example/:id/:name', (req, res) {}, middleware: [_ExampleMiddleware()]);

  await app.listen(); //Listening on port 3000
}

and End-Point callback too !

class _RequestController with CallableRequestMixin {
  @override
  FutureOr call(HttpRequest req, HttpResponse res) => "I'm a Class :)";
}

void main() async {
  final app = Alfred();

  app.get('/text', _RequestController());

  await app.listen(6565); //Listening on port 6565
}

@tomassasovsky
Copy link

Hey @NathanDraco22! I don't think this makes any sense, as the call function comes out of the box with every Dart class and does not add any functionality.

And since it is functional without the need for this, I don't know how much sense it makes.

I'm currently using what I've called RouteHandlers, and this is my implementation of them:

import 'dart:async';

import 'package:alfred/alfred.dart';
import 'package:alfredito/src/validators/validators.dart';
import 'package:meta/meta.dart';

part 'controller.dart';
part 'middleware.dart';

/// {@template route_handler}
/// A Route Handler is a class that can be registered as a callback.
/// {@endtemplate}
abstract class RouteHandler<T extends RouteHandler<T>> {
  /// Here you can define all your variables that will be available in the
  /// route handler.
  FutureOr<dynamic> defineVars(HttpRequest req, HttpResponse res) async {}

  /// This is the method that is called when the route is.
  /// It first creates a new instance of the class itself, then proceeds to
  /// call the [defineVars] function so that every variable gets grabbed,
  /// and then executes the [run] function.
  FutureOr<dynamic> call(HttpRequest req, HttpResponse res) async {
    final instance = newInstance;
    // this handles the request
    await instance.defineVars(req, res);
    req.validate();
    await instance.run(req, res);
  }

  /// This is where you should handle all the logic.
  FutureOr<dynamic> run(HttpRequest req, HttpResponse res);

  /// Creates a new instance of this class (used to avoid usage of dart: mirrors)
  T get newInstance;
}

and an example of a controller/middleware:

class ExampleController extends RouteHandler<ExampleController> {
  late String apiKey;

  @override
  FutureOr<void> defineVars(HttpRequest req, HttpResponse res) async {
    // here you can grab and process the variables
    // that come from the request itself, and save them as vars inside the class
    final _apiKey = req.headers.value('Authorization');
    if (_apiKey == null || _apiKey.isEmpty) {
      throw AlfredException(401, {'message': 'authentication failed'});
    }
    apiKey = _apiKey;
  }

  @override
  FutureOr<dynamic> run(HttpRequest req, HttpResponse res) async {
    // here you can do whatever you want functionality-wise
    await res.json(
      <String, String>{
        'message': 'hello world',
        'apiKey': apiKey,
      },
    );
  }

  @override
  ExampleController get newInstance => ExampleController();
}

@NathanDraco22
Copy link
Contributor Author

Yeah you're right, this Mixin is only like tool or helper, to create a faster function signature.
I thought like a Expanded widget in flutter, is only a Flexible with some common settings,
This mixin is only like a helper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants