platform/packages/shelf
2024-10-12 19:17:24 -07:00
..
example Refactor: changing namespace, imports, re-branding 2024-10-12 18:45:27 -07:00
lib Refactor: changing namespace, imports, re-branding 2024-10-12 18:45:27 -07:00
test Refactor: changing namespace, imports, re-branding 2024-10-12 18:45:27 -07:00
analysis_options.yaml Updated angel3_shelf 2021-09-14 09:23:03 +08:00
AUTHORS.md Merged from sdk-2.12.x_nnbd 2021-06-20 20:37:20 +08:00
CHANGELOG.md Refactor: changing namespace, imports, re-branding 2024-10-12 19:17:24 -07:00
LICENSE Updated angel3_shelf 2021-09-14 09:23:03 +08:00
pubspec.yaml Refactor: changing namespace, imports, re-branding 2024-10-12 18:45:27 -07:00
README.md Refactor: changing namespace, imports, re-branding 2024-10-12 19:17:24 -07:00

Protevus Shelf

Pub Version (including pre-releases) Null Safety Discord License

Replacement of package:angel_shelf with breaking changes to support NNBD.

Shelf interop with Protevus. This package lets you run package:shelf handlers via a custom adapter. Use the code in this repo to embed existing Protevus/shelf apps into other Protevus/shelf applications. This way, you can migrate legacy applications without having to rewrite your business logic. This will make it easy to layer your API over a production application, rather than having to port code.

Usage

embedShelf

This is a compliant shelf adapter that acts as an Protevus request handler. You can use it as a middleware, or attach it to individual routes.

import 'dart:io';
import 'package:protevus_framework/protevus_framework.dart';
import 'package:protevus_shelf/protevus_shelf.dart';
import 'package:shelf/shelf.dart' as shelf;
import 'api/api.dart';

void main() async {
  var app = Protevus();
  var http = ProtevusHttp(app);

  // Protevus routes on top
  await app.mountController<ApiController>();

  // Re-route all other traffic to an
  // existing application.
  app.fallback(embedShelf(
    shelf.Pipeline()
      .addMiddleware(shelf.logRequests())
      .addHandler(_echoRequest)
  ));

  // Or, only on a specific route:
  app.get('/shelf', wrappedShelfHandler);

  await http.startServer(InternetAddress.loopbackIPV4, 3000);
  print(http.uri);
}

Communicating with Protevus with embedShelf

You can communicate with Protevus:

handleRequest(shelf.Request request) {
  // Access original Protevus request...
  var req = request.context['angel_shelf.request'] as RequestContext;

  // ... And then interact with it.
  req.container.registerNamedSingleton<Foo>('from_shelf', Foo());

  // `req.container` is also available.
  var container = request.context['angel_shelf.container'] as Container;
  container.make<Truck>().drive();
}

ProtevusShelf

Protevus brought about the generic Driver class, which is implemented by ProtevusHttp, ProtevusHttp2, ProtevusGopher, etc., and provides the core infrastructure for request handling in Protevus. ProtevusShelf is an implementation that wraps shelf requests and responses in their Protevus equivalents. Using it is as simple using as using ProtevusHttp, or any other driver:

// Create an ProtevusShelf driver.
// If we have startup hooks we want to run, we need to call
// `startServer`. Otherwise, it can be omitted.
// Of course, if you call `startServer`, know that to run
// shutdown/cleanup logic, you need to call `close` eventually,
// too.
var angelShelf = ProtevusShelf(app);
await angelShelf.startServer();

await shelf_io.serve(angelShelf.handler, InternetAddress.loopbackIPv4, 8081);

You can also use the ProtevusShelf driver as a shelf middleware - just use angelShelf.middleware instead of angelShelf.handler. When used as a middleware, if the Protevus response context is still open after all handlers run (i.e. no routes were matched), the next shelf handler will be called.

var handler = shelf.Pipeline()
  .addMiddleware(angelShelf.middleware)
  .addHandler(createStaticHandler(...));