Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(335)

Side by Side Diff: pkg/shelf/README.md

Issue 814113004: Pull args, intl, logging, shelf, and source_maps out of the SDK. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Also csslib. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/shelf/LICENSE ('k') | pkg/shelf/example/example_server.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 ## Web Server Middleware for Dart
2
3 ## Introduction
4
5 **Shelf** makes it easy to create and compose **web servers** and **parts of web
6 servers**. How?
7
8 * Expose a small set of simple types.
9 * Map server logic into a simple function: a single argument for the request,
10 the response is the return value.
11 * Trivially mix and match synchronous and asynchronous processing.
12 * Flexibliity to return a simple string or a byte stream with the same model.
13
14 ## Example
15
16 See `example/example_server.dart`
17
18 ```dart
19 import 'package:shelf/shelf.dart' as shelf;
20 import 'package:shelf/shelf_io.dart' as io;
21
22 void main() {
23 var handler = const shelf.Pipeline().addMiddleware(shelf.logRequests())
24 .addHandler(_echoRequest);
25
26 io.serve(handler, 'localhost', 8080).then((server) {
27 print('Serving at http://${server.address.host}:${server.port}');
28 });
29 }
30
31 shelf.Response _echoRequest(shelf.Request request) {
32 return new shelf.Response.ok('Request for "${request.url}"');
33 }
34 ```
35
36 ## Handlers and Middleware
37
38 A [handler][] is any function that handles a [shelf.Request][] and returns a
39 [shelf.Response][]. It can either handle the request itself--for example, a
40 static file server that looks up the requested URI on the filesystem--or it can
41 do some processing and forward it to another handler--for example, a logger that
42 prints information about requests and responses to the command line.
43
44 [handler]: http://www.dartdocs.org/documentation/shelf/latest/index.html#shelf/s helf@id_Handler
45
46 [shelf.Request]: http://www.dartdocs.org/documentation/shelf/latest/index.html#s helf/shelf.Request
47
48 [shelf.Response]: http://www.dartdocs.org/documentation/shelf/latest/index.html #shelf/shelf.Response
49
50 The latter kind of handler is called "[middleware][]", since it sits in the
51 middle of the server stack. Middleware can be thought of as a function that
52 takes a handler and wraps it in another handler to provide additional
53 functionality. A Shelf application is usually composed of many layers of
54 middleware with one or more handlers at the very center; the [shelf.Pipeline][]
55 class makes this sort of application easy to construct.
56
57 [middleware]: http://www.dartdocs.org/documentation/shelf/latest/index.html#shel f/shelf@id_Middleware
58
59 [shelf.Pipeline]: http://www.dartdocs.org/documentation/shelf/latest/index.html #shelf/shelf.Pipeline
60
61 Some middleware can also take multiple handlers and call one or more of them for
62 each request. For example, a routing middleware might choose which handler to
63 call based on the request's URI or HTTP method, while a cascading middleware
64 might call each one in sequence until one returns a successful response.
65
66 ## Adapters
67
68 An adapter is any code that creates [shelf.Request][] objects, passes them to a
69 handler, and deals with the resulting [shelf.Response][]. For the most part,
70 adapters forward requests from and responses to an underlying HTTP server;
71 [shelf_io.serve][] is this sort of adapter. An adapter might also synthesize
72 HTTP requests within the browser using `window.location` and `window.history`,
73 or it might pipe requests directly from an HTTP client to a Shelf handler.
74
75 [shelf_io.serve]: http://www.dartdocs.org/documentation/shelf/latest/index.html# shelf/shelf-io@id_serve
76
77 When implementing an adapter, some rules must be followed. The adapter must not
78 pass the `url` or `scriptName` parameters to [new shelf.Request][]; it should
79 only pass `requestedUri`. If it passes the `context` parameter, all keys must
80 begin with the adapter's package name followed by a period. If multiple headers
81 with the same name are received, the adapter must collapse them into a single
82 header separated by commas as per [RFC 2616 section 4.2][].
83
84 [new shelf.Request]: http://www.dartdocs.org/documentation/shelf/latest/index.ht ml#shelf/shelf.Request@id_Request-
85
86 [RFC 2616 section 4.2]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html
87
88 An adapter must handle all errors from the handler, including the handler
89 returning a `null` response. It should print each error to the console if
90 possible, then act as though the handler returned a 500 response. The adapter
91 may include body data for the 500 response, but this body data must not include
92 information about the error that occurred. This ensures that unexpected errors
93 don't result in exposing internal information in production by default; if the
94 user wants to return detailed error descriptions, they should explicitly include
95 middleware to do so.
96
97 An adapter should include information about itself in the Server header of the
98 response by default. If the handler returns a response with the Server header
99 set, that must take precedence over the adapter's default header.
100
101 An adapter should include the Date header with the time the handler returns a
102 response. If the handler returns a response with the Date header set, that must
103 take precedence.
104
105 An adapter should ensure that asynchronous errors thrown by the handler don't
106 cause the application to crash, even if they aren't reported by the future
107 chain. Specifically, these errors shouldn't be passed to the root zone's error
108 handler; however, if the adapter is run within another error zone, it should
109 allow these errors to be passed to that zone. The following function can be used
110 to capture only errors that would otherwise be top-leveled:
111
112 ```dart
113 /// Run [callback] and capture any errors that would otherwise be top-leveled.
114 ///
115 /// If [this] is called in a non-root error zone, it will just run [callback]
116 /// and return the result. Otherwise, it will capture any errors using
117 /// [runZoned] and pass them to [onError].
118 catchTopLevelErrors(callback(), void onError(error, StackTrace stackTrace)) {
119 if (Zone.current.inSameErrorZone(Zone.ROOT)) {
120 return runZoned(callback, onError: onError);
121 } else {
122 return callback();
123 }
124 }
125 ```
126
127 ## Inspiration
128
129 * [Connect](http://www.senchalabs.org/connect/) for NodeJS.
130 * Read [this great write-up](http://howtonode.org/connect-it) to understand
131 the overall philosophy of all of these models.
132 * [Rack](http://rack.github.io/) for Ruby.
133 * [WSGI](http://legacy.python.org/dev/peps/pep-3333/) for Python.
OLDNEW
« no previous file with comments | « pkg/shelf/LICENSE ('k') | pkg/shelf/example/example_server.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698