CINXE.COM
shelf | Dart package
<!DOCTYPE html> <html lang="en-us"><head><script src="https://www.googletagmanager.com/gtm.js?id=GTM-MX6DBN9" async="async"></script><script src="/static/hash-v0koh7hq/js/gtm.js" async="async"></script><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="ie=edge"/><meta name="viewport" content="width=device-width, initial-scale=1"/><meta name="twitter:card" content="summary"/><meta name="twitter:site" content="@dart_lang"/><meta name="twitter:description" content="A model for web server middleware that encourages composition and easy reuse. "/><meta name="twitter:image" content="https://pub.dev/static/hash-v0koh7hq/img/pub-dev-icon-cover-image.png"/><meta property="og:type" content="website"/><meta property="og:site_name" content="Dart packages"/><meta property="og:title" content="shelf | Dart package"/><meta property="og:description" content="A model for web server middleware that encourages composition and easy reuse. "/><meta property="og:image" content="https://pub.dev/static/hash-v0koh7hq/img/pub-dev-icon-cover-image.png"/><meta property="og:url" content="https://pub.dev/packages/shelf"/><title>shelf | Dart package</title><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;700&family=Google+Sans+Display:wght@400&family=Google+Sans+Text:wght@400;500;700&family=Google+Sans+Mono:wght@400;700&display=swap"/><link rel="shortcut icon" href="/favicon.ico?hash=nk4nss8c7444fg0chird9erqef2vkhb8"/><link rel="stylesheet" href="https://www.gstatic.com/glue/v25_0/ccb.min.css"/><link rel="search" type="application/opensearchdescription+xml" title="Dart packages" href="/osd.xml"/><link rel="canonical" href="https://pub.dev/packages/shelf"/><meta name="description" content="A model for web server middleware that encourages composition and easy reuse. "/><link rel="alternate" type="application/atom+xml" title="Updated Packages Feed for Pub" href="/feed.atom"/><link rel="stylesheet" type="text/css" href="/static/hash-v0koh7hq/material/bundle/styles.css"/><link rel="stylesheet" type="text/css" href="/static/hash-v0koh7hq/css/style.css"/><script src="/static/hash-v0koh7hq/material/bundle/script.min.js" defer="defer"></script><script src="/static/hash-v0koh7hq/js/script.dart.js" defer="defer"></script><script src="https://www.gstatic.com/brandstudio/kato/cookie_choice_component/cookie_consent_bar.v3.js" defer="defer" data-autoload-cookie-consent-bar="true"></script><meta name="pub-page-data" content="eyJwa2dEYXRhIjp7InBhY2thZ2UiOiJzaGVsZiIsInZlcnNpb24iOiIxLjQuMiIsImxpa2VzIjo5MzAsInB1Ymxpc2hlcklkIjoidG9vbHMuZGFydC5kZXYiLCJpc0Rpc2NvbnRpbnVlZCI6ZmFsc2UsImlzTGF0ZXN0Ijp0cnVlfSwic2Vzc2lvbkF3YXJlIjpmYWxzZX0="/><link rel="preload" href="/static/hash-v0koh7hq/highlight/highlight-with-init.js" as="script"/></head><body class="light-theme"><script src="/static/hash-v0koh7hq/js/dark-init.js"></script><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-MX6DBN9" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><div class="site-header"><button class="hamburger" aria-label="menu toggle"></button><a class="logo" href="/" aria-label="Go to the landing page of pub.dev"><img class="site-logo" src="/static/hash-v0koh7hq/img/pub-dev-logo.svg" alt="" width="140" height="30" role="presentation"/></a><div class="site-header-space"></div><div class="site-header-mask"></div><div class="site-header-search"><form action="/packages" method="GET"><input class="site-header-search-input" name="q" placeholder="New search..." autocomplete="on" title="Search"/></form></div><nav class="site-header-nav scroll-container"><div class="nav-login-container"><button id="-account-login" class="nav-main-button link">Sign in</button></div><div class="nav-container nav-help-container hoverable"><button class="nav-main-button">Help</button><div class="nav-hover-popup"><div class="nav-table-columns"><div class="nav-table-column"><h3>pub.dev</h3><a class="nav-link" href="/help/search" rel="noopener" target="_blank">Searching for packages</a><a class="nav-link" href="/help/scoring" rel="noopener" target="_blank">Package scoring and pub points</a></div><div class="nav-table-column"><h3>Flutter</h3><a class="nav-link" href="https://flutter.dev/using-packages/" rel="noopener" target="_blank">Using packages</a><a class="nav-link" href="https://flutter.dev/developing-packages/" rel="noopener" target="_blank">Developing packages and plugins</a><a class="nav-link" href="https://dart.dev/tools/pub/publishing" rel="noopener" target="_blank">Publishing a package</a></div><div class="nav-table-column"><h3>Dart</h3><a class="nav-link" href="https://dart.dev/guides/packages" rel="noopener" target="_blank">Using packages</a><a class="nav-link" href="https://dart.dev/tools/pub/publishing" rel="noopener" target="_blank">Publishing a package</a></div></div></div></div><div class="nav-container nav-help-container-mobile foldable"><h3 class="foldable-button">pub.dev <img class="foldable-icon" src="/static/hash-v0koh7hq/img/nav-mobile-foldable-icon.svg" alt="toggle folding of the section" width="13" height="6"/></h3><div class="foldable-content"><a class="nav-link" href="/help/search" rel="noopener" target="_blank">Searching for packages</a><a class="nav-link" href="/help/scoring" rel="noopener" target="_blank">Package scoring and pub points</a></div></div><div class="nav-container nav-help-container-mobile foldable"><h3 class="foldable-button">Flutter <img class="foldable-icon" src="/static/hash-v0koh7hq/img/nav-mobile-foldable-icon.svg" alt="toggle folding of the section" width="13" height="6"/></h3><div class="foldable-content"><a class="nav-link" href="https://flutter.dev/using-packages/" rel="noopener" target="_blank">Using packages</a><a class="nav-link" href="https://flutter.dev/developing-packages/" rel="noopener" target="_blank">Developing packages and plugins</a><a class="nav-link" href="https://dart.dev/tools/pub/publishing" rel="noopener" target="_blank">Publishing a package</a></div></div><div class="nav-container nav-help-container-mobile foldable"><h3 class="foldable-button">Dart <img class="foldable-icon" src="/static/hash-v0koh7hq/img/nav-mobile-foldable-icon.svg" alt="toggle folding of the section" width="13" height="6"/></h3><div class="foldable-content"><a class="nav-link" href="https://dart.dev/guides/packages" rel="noopener" target="_blank">Using packages</a><a class="nav-link" href="https://dart.dev/tools/pub/publishing" rel="noopener" target="_blank">Publishing a package</a></div></div></nav><button class="-pub-theme-toggle" aria-label="light/dark theme toggle"></button></div><div id="banner-container"></div><main class="container"><div class="detail-wrapper -active -has-info-box"><div class="detail-header -is-loose"><div class="detail-container"><div class="detail-header-outer-block"><div class="detail-header-content-block"><h1 class="title pub-monochrome-icon-hoverable">shelf 1.4.2 <span class="pkg-page-title-copy"><img class="pub-monochrome-icon pkg-page-title-copy-icon filter-invert-on-dark" src="/static/hash-v0koh7hq/img/content-copy-icon.svg" alt="copy "shelf: ^1.4.2" to clipboard" width="18" height="18" title="Copy "shelf: ^1.4.2" to clipboard" data-copy-content="shelf: ^1.4.2" data-ga-click-event="copy-package-version"/><div class="pkg-page-title-copy-feedback"><span class="code">shelf: ^1.4.2</span> copied to clipboard</div></span></h1><div class="metadata">Published <span><a class="-x-ago" href="" title="Jun 21, 2024" role="button" data-timestamp="1718992024083">8 months ago</a></span> • <a class="-pub-publisher" href="/publishers/tools.dart.dev"><img class="-pub-publisher-shield filter-invert-on-dark" src="/static/hash-v0koh7hq/img/material-icon-verified.svg" alt="verified publisher" width="14" height="14" title="Published by a pub.dev verified publisher"/>tools.dart.dev</a><span class="package-badge" title="Package is compatible with Dart 3.">Dart 3 compatible</span></div><div class="detail-tags-and-like"><div class="detail-tags"><div class="-pub-tag-badge"><span class="tag-badge-main">SDK</span><a class="tag-badge-sub" href="/packages?q=sdk%3Adart" rel="nofollow" title="Packages compatible with Dart SDK">Dart</a><a class="tag-badge-sub" href="/packages?q=sdk%3Aflutter" rel="nofollow" title="Packages compatible with Flutter SDK">Flutter</a></div><div class="-pub-tag-badge"><span class="tag-badge-main">Platform</span><a class="tag-badge-sub" href="/packages?q=platform%3Aandroid" rel="nofollow" title="Packages compatible with Android platform">Android</a><a class="tag-badge-sub" href="/packages?q=platform%3Aios" rel="nofollow" title="Packages compatible with iOS platform">iOS</a><a class="tag-badge-sub" href="/packages?q=platform%3Alinux" rel="nofollow" title="Packages compatible with Linux platform">Linux</a><a class="tag-badge-sub" href="/packages?q=platform%3Amacos" rel="nofollow" title="Packages compatible with macOS platform">macOS</a><a class="tag-badge-sub" href="/packages?q=platform%3Aweb" rel="nofollow" title="Packages compatible with Web platform">web</a><a class="tag-badge-sub" href="/packages?q=platform%3Awindows" rel="nofollow" title="Packages compatible with Windows platform">Windows</a></div></div><div class="detail-like"><button id="-pub-like-icon-button" class="mdc-icon-button" data-ga-click-event="toggle-like" aria-pressed="false" title="Like this package"><img class="mdc-icon-button__icon" src="/static/hash-v0koh7hq/img/like-inactive.svg" alt="liked status: inactive" width="18" height="18"/><img class="mdc-icon-button__icon mdc-icon-button__icon--on" src="/static/hash-v0koh7hq/img/like-active.svg" alt="liked status: active" width="18" height="18"/></button><span class="likes-count"><span id="likes-count">930</span></span></div></div></div></div></div></div><div class="detail-container"><div class="detail-lead"><div class="detail-metadata-toggle"><div class="detail-metadata-toggle-icon">→</div><h3 class="detail-lead-title">Metadata</h3></div><p class="detail-lead-text">A model for web server middleware that encourages composition and easy reuse. </p><p class="detail-lead-more"><a class="detail-metadata-toggle">More...</a></p></div></div><div class="detail-body"><div class="detail-tabs"><div class="detail-tabs-wide-header"><div class="detail-container"><ul class="detail-tabs-header"><li class="detail-tab tab-button detail-tab-readme-title -active">Readme</li><li class="detail-tab tab-link detail-tab-changelog-title"><a href="/packages/shelf/changelog" role="button">Changelog</a></li><li class="detail-tab tab-link detail-tab-example-title"><a href="/packages/shelf/example" role="button">Example</a></li><li class="detail-tab tab-link detail-tab-installing-title"><a href="/packages/shelf/install" role="button">Installing</a></li><li class="detail-tab tab-link detail-tab-versions-title"><a href="/packages/shelf/versions" role="button">Versions</a></li><li class="detail-tab tab-link detail-tab-analysis-title"><a href="/packages/shelf/score" role="button">Scores</a></li></ul></div></div><div class="detail-container detail-body-main"><div class="detail-tabs-content"><section class="tab-content detail-tab-readme-content -active markdown-body"><p><a href="https://pub.dev/packages/shelf"><img src="https://img.shields.io/pub/v/shelf.svg" alt="pub package"></a> <a href="https://pub.dev/packages/shelf/publisher"><img src="https://img.shields.io/pub/publisher/shelf.svg" alt="package publisher"></a></p> <h2 class="hash-header" id="web-server-middleware-for-dart">Web Server Middleware for Dart <a href="#web-server-middleware-for-dart" class="hash-link">#</a></h2> <p><strong>Shelf</strong> makes it easy to create and compose <strong>web servers</strong> and <strong>parts of web servers</strong>. How?</p> <ul> <li>Expose a small set of simple types.</li> <li>Map server logic into a simple function: a single argument for the request, the response is the return value.</li> <li>Trivially mix and match synchronous and asynchronous processing.</li> <li>Flexibility to return a simple string or a byte stream with the same model.</li> </ul> <p>See the <a href="https://dart.dev/tutorials/server/httpserver">Dart HTTP server documentation</a> for more information. You may also want to look at <a href="https://pub.dev/packages/shelf_router">package:shelf_router</a> and <a href="https://pub.dev/packages/shelf_static">package:shelf_static</a> as examples of packages that build on and extend <code>package:shelf</code>.</p> <h2 class="hash-header" id="example">Example <a href="#example" class="hash-link">#</a></h2> <p>See <code>example/example.dart</code></p> <pre><code class="language-dart">import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as shelf_io; void main() async { var handler = const Pipeline().addMiddleware(logRequests()).addHandler(_echoRequest); var server = await shelf_io.serve(handler, 'localhost', 8080); // Enable content compression server.autoCompress = true; print('Serving at http://${server.address.host}:${server.port}'); } Response _echoRequest(Request request) => Response.ok('Request for "${request.url}"'); </code></pre> <h2 class="hash-header" id="handlers-and-middleware">Handlers and Middleware <a href="#handlers-and-middleware" class="hash-link">#</a></h2> <p>A <a href="https://pub.dev/documentation/shelf/latest/shelf/Handler.html">Handler</a> is any function that handles a <a href="https://pub.dev/documentation/shelf/latest/shelf/Request-class.html">Request</a> and returns a <a href="https://pub.dev/documentation/shelf/latest/shelf/Response-class.html">Response</a>. It can either handle the request itself–for example, a static file server that looks up the requested URI on the filesystem–or it can do some processing and forward it to another handler–for example, a logger that prints information about requests and responses to the command line.</p> <p>The latter kind of handler is called "<a href="https://pub.dev/documentation/shelf/latest/shelf/Middleware.html">middleware</a>", since it sits in the middle of the server stack. Middleware can be thought of as a function that takes a handler and wraps it in another handler to provide additional functionality. A Shelf application is usually composed of many layers of middleware with one or more handlers at the very center; the <a href="https://pub.dev/documentation/shelf/latest/shelf/Pipeline-class.html">Pipeline</a> class makes this sort of application easy to construct.</p> <p>Some middleware can also take multiple handlers and call one or more of them for each request. For example, a routing middleware might choose which handler to call based on the request's URI or HTTP method, while a cascading middleware might call each one in sequence until one returns a successful response.</p> <p>Middleware that routes requests between handlers should be sure to update each request's <a href="https://pub.dev/documentation/shelf/latest/shelf/Request/handlerPath.html"><code>handlerPath</code></a> and <a href="https://pub.dev/documentation/shelf/latest/shelf/Request/url.html"><code>url</code></a>. This allows inner handlers to know where they are in the application so they can do their own routing correctly. This can be easily accomplished using <a href="https://pub.dev/documentation/shelf/latest/shelf/Request/change.html"><code>Request.change()</code></a>:</p> <pre><code class="language-dart">// In an imaginary routing middleware... var component = request.url.pathSegments.first; var handler = _handlers[component]; if (handler == null) return Response.notFound(null); // Create a new request just like this one but with whatever URL comes after // [component] instead. return handler(request.change(path: component)); </code></pre> <h2 class="hash-header" id="adapters">Adapters <a href="#adapters" class="hash-link">#</a></h2> <p>An adapter is any code that creates <a href="https://pub.dev/documentation/shelf/latest/shelf/Request-class.html">Request</a> objects, passes them to a handler, and deals with the resulting <a href="https://pub.dev/documentation/shelf/latest/shelf/Response-class.html">Response</a>. For the most part, adapters forward requests from and responses to an underlying HTTP server; <a href="https://pub.dev/documentation/shelf/latest/shelf_io/serve.html">shelf_io.serve</a> is this sort of adapter. An adapter might also synthesize HTTP requests within the browser using <code>window.location</code> and <code>window.history</code>, or it might pipe requests directly from an HTTP client to a Shelf handler.</p> <h3 class="hash-header" id="api-requirements">API Requirements <a href="#api-requirements" class="hash-link">#</a></h3> <p>An adapter must handle all errors from the handler, including the handler returning a <code>null</code> response. It should print each error to the console if possible, then act as though the handler returned a 500 response. The adapter may include body data for the 500 response, but this body data must not include information about the error that occurred. This ensures that unexpected errors don't result in exposing internal information in production by default; if the user wants to return detailed error descriptions, they should explicitly include middleware to do so.</p> <p>An adapter should ensure that asynchronous errors thrown by the handler don't cause the application to crash, even if they aren't reported by the future chain. Specifically, these errors shouldn't be passed to the root zone's error handler; however, if the adapter is run within another error zone, it should allow these errors to be passed to that zone. The following function can be used to capture only errors that would otherwise be top-leveled:</p> <pre><code class="language-dart">/// Run [callback] and capture any errors that would otherwise be top-leveled. /// /// If `this` is called in a non-root error zone, it will just run [callback] /// and return the result. Otherwise, it will capture any errors using /// [runZoned] and pass them to [onError]. void catchTopLevelErrors( void Function() callback, void Function(Object error, StackTrace stackTrace) onError, ) { if (Zone.current.inSameErrorZone(Zone.root)) { return runZonedGuarded(callback, onError); } else { return callback(); } } </code></pre> <p>An adapter that knows its own URL should provide an implementation of the <a href="https://pub.dev/documentation/shelf/latest/shelf/Server-class.html"><code>Server</code></a> interface.</p> <h3 class="hash-header" id="request-requirements">Request Requirements <a href="#request-requirements" class="hash-link">#</a></h3> <p>When implementing an adapter, some rules must be followed. The adapter must not pass the <code>url</code> or <code>handlerPath</code> parameters to <a href="https://pub.dev/documentation/shelf/latest/shelf/Request-class.html">Request</a>; it should only pass <code>requestedUri</code>. If it passes the <code>context</code> parameter, all keys must begin with the adapter's package name followed by a period. If multiple headers with the same name are received, the adapter must collapse them into a single header separated by commas as per <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html" rel="ugc">RFC 2616 section 4.2</a>.</p> <p>If the underlying request uses a chunked transfer coding, the adapter must decode the body before passing it to <a href="https://pub.dev/documentation/shelf/latest/shelf/Request-class.html">Request</a> and should remove the <code>Transfer-Encoding</code> header. This ensures that message bodies are chunked if and only if the headers declare that they are.</p> <h3 class="hash-header" id="response-requirements">Response Requirements <a href="#response-requirements" class="hash-link">#</a></h3> <p>An adapter must not add or modify any <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.1" rel="ugc">entity headers</a> for a response.</p> <p>If <em>none</em> of the following conditions are true, the adapter must apply <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1" rel="ugc">chunked transfer coding</a> to a response's body and set its Transfer-Encoding header to <code>chunked</code>:</p> <ul> <li>The status code is less than 200, or equal to 204 or 304.</li> <li>A Content-Length header is provided.</li> <li>The Content-Type header indicates the MIME type <code>multipart/byteranges</code>.</li> <li>The Transfer-Encoding header is set to anything other than <code>identity</code>.</li> </ul> <p>Adapters may find the <a href="https://pub.dev/documentation/shelf/latest/shelf/addChunkedEncoding.html"><code>addChunkedEncoding()</code></a> middleware useful for implementing this behavior, if the underlying server doesn't implement it manually.</p> <p>When responding to a HEAD request, the adapter must not emit an entity body. Otherwise, it shouldn't modify the entity body in any way.</p> <p>An adapter should include information about itself in the Server header of the response by default. If the handler returns a response with the Server header set, that must take precedence over the adapter's default header.</p> <p>An adapter should include the Date header with the time the handler returns a response. If the handler returns a response with the Date header set, that must take precedence.</p> <h2 class="hash-header" id="inspiration">Inspiration <a href="#inspiration" class="hash-link">#</a></h2> <ul> <li><a href="https://github.com/senchalabs/connect" rel="ugc">Connect</a> for NodeJS.</li> <li><a href="https://github.com/rack/rack" rel="ugc">Rack</a> for Ruby.</li> </ul> </section></div></div></div><aside class="detail-info-box"><a class="packages-scores" href="/packages/shelf/score"><div class="packages-score packages-score-like"><div class="packages-score-value -has-value"><span class="packages-score-value-number">930</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">likes</div></div><div class="packages-score packages-score-health"><div class="packages-score-value -has-value"><span class="packages-score-value-number">160</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">points</div></div><div class="packages-score packages-score-downloads" title="Number of downloads of this package during the past 30 days"><div class="packages-score-value -has-value"><span class="packages-score-value-number">5.65M</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">downloads</div></div></a><h3 class="title">Publisher</h3><p><a href="/publishers/tools.dart.dev"><img class="-pub-publisher-shield filter-invert-on-dark" src="/static/hash-v0koh7hq/img/material-icon-verified.svg" alt="verified publisher" width="14" height="14" title="Published by a pub.dev verified publisher"/>tools.dart.dev</a></p><h3 class="title">Weekly Downloads</h3><div id="-weekly-downloads-sparkline" class="weekly-downloads-sparkline" data-widget="weekly-sparkline" data-weekly-sparkline-points="gM2zZ1ZQFACv9xIAaA0VAEBfEwCXxhEA/2MRAP8wDADW5AgAVPUOAIBiEwCFShEAi2IPAER1EADo8w8AoZ0PAKLLDwCV6xAAtG8RAN6lDgBcTA8ArGgQAJZADgBFSw4ANasPAMKCDgBj8Q8A2cQOABlXDwCsUg8AjXEPANQgDwCWkw4A1zMOAH+JEADO3g4A7h4OAF4VDgDPYQ4A+oAOADF0DwCZyQ4A+0EOAGgKEQAIkhIAZqUPANzmEAC2DhAAOrAQALKiEQDJFxIArW0RAB+vEQA="></div><h3 class="title pkg-infobox-metadata">Metadata</h3><p>A model for web server middleware that encourages composition and easy reuse. </p><p><a class="link" href="https://github.com/dart-lang/shelf/tree/master/pkgs/shelf" rel="ugc">Repository (GitHub)</a><br/><a class="link" href="https://github.com/dart-lang/shelf/blob/master/CONTRIBUTING.md" rel="ugc">Contributing</a><br/></p><h3 class="title">Topics</h3><p><a class="topics-tag" href="/packages?q=topic%3Aserver" rel="nofollow">#server</a> <a class="topics-tag" href="/packages?q=topic%3Ashelf" rel="nofollow">#shelf</a> <a class="topics-tag" href="/packages?q=topic%3Abackend" rel="nofollow">#backend</a></p><h3 class="title">Documentation</h3><p><a class="link" href="/documentation/shelf/latest/">API reference</a><br/></p><h3 class="title">License</h3><p><img class="inline-icon-img filter-invert-on-dark" src="/static/hash-v0koh7hq/img/material-icon-balance.svg" alt="" width="14" height="14" role="presentation"/>BSD-3-Clause (<a href="/packages/shelf/license">license</a>)</p><h3 class="title">Dependencies</h3><p><a href="/packages/async" title="^2.5.0">async</a>, <a href="/packages/collection" title="^1.15.0">collection</a>, <a href="/packages/http_parser" title="^4.1.0">http_parser</a>, <a href="/packages/path" title="^1.8.0">path</a>, <a href="/packages/stack_trace" title="^1.10.0">stack_trace</a>, <a href="/packages/stream_channel" title="^2.1.0">stream_channel</a></p><h3 class="title">More</h3><p><a href="/packages?q=dependency%3Ashelf" rel="nofollow">Packages that depend on shelf</a></p></aside></div><script type="application/ld+json">{"@context":"http\u003a\u002f\u002fschema.org","@type":"SoftwareSourceCode","name":"shelf","version":"1.4.2","description":"shelf - A model for web server middleware that encourages composition and easy reuse.\u000a","url":"https\u003a\u002f\u002fpub.dev\u002fpackages\u002fshelf","dateCreated":"2014-01-02T04\u003a21\u003a30.895Z","dateModified":"2024-06-21T17\u003a47\u003a04.083038Z","programmingLanguage":"Dart","image":"https\u003a\u002f\u002fpub.dev\u002fstatic\u002fimg\u002fpub-dev-icon-cover-image.png","license":"https\u003a\u002f\u002fpub.dev\u002fpackages\u002fshelf\u002flicense"}</script></div><div class="detail-metadata"><h3 class="detail-metadata-title"><span class="detail-metadata-toggle">←</span> Metadata</h3><div class="detail-info-box"><a class="packages-scores" href="/packages/shelf/score"><div class="packages-score packages-score-like"><div class="packages-score-value -has-value"><span class="packages-score-value-number">930</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">likes</div></div><div class="packages-score packages-score-health"><div class="packages-score-value -has-value"><span class="packages-score-value-number">160</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">points</div></div><div class="packages-score packages-score-downloads" title="Number of downloads of this package during the past 30 days"><div class="packages-score-value -has-value"><span class="packages-score-value-number">5.65M</span><span class="packages-score-value-sign"></span></div><div class="packages-score-label">downloads</div></div></a><h3 class="title">Publisher</h3><p><a href="/publishers/tools.dart.dev"><img class="-pub-publisher-shield filter-invert-on-dark" src="/static/hash-v0koh7hq/img/material-icon-verified.svg" alt="verified publisher" width="14" height="14" title="Published by a pub.dev verified publisher"/>tools.dart.dev</a></p><h3 class="title">Weekly Downloads</h3><div id="-weekly-downloads-sparkline" class="weekly-downloads-sparkline" data-widget="weekly-sparkline" data-weekly-sparkline-points="gM2zZ1ZQFACv9xIAaA0VAEBfEwCXxhEA/2MRAP8wDADW5AgAVPUOAIBiEwCFShEAi2IPAER1EADo8w8AoZ0PAKLLDwCV6xAAtG8RAN6lDgBcTA8ArGgQAJZADgBFSw4ANasPAMKCDgBj8Q8A2cQOABlXDwCsUg8AjXEPANQgDwCWkw4A1zMOAH+JEADO3g4A7h4OAF4VDgDPYQ4A+oAOADF0DwCZyQ4A+0EOAGgKEQAIkhIAZqUPANzmEAC2DhAAOrAQALKiEQDJFxIArW0RAB+vEQA="></div><h3 class="title pkg-infobox-metadata">Metadata</h3><p>A model for web server middleware that encourages composition and easy reuse. </p><p><a class="link" href="https://github.com/dart-lang/shelf/tree/master/pkgs/shelf" rel="ugc">Repository (GitHub)</a><br/><a class="link" href="https://github.com/dart-lang/shelf/blob/master/CONTRIBUTING.md" rel="ugc">Contributing</a><br/></p><h3 class="title">Topics</h3><p><a class="topics-tag" href="/packages?q=topic%3Aserver" rel="nofollow">#server</a> <a class="topics-tag" href="/packages?q=topic%3Ashelf" rel="nofollow">#shelf</a> <a class="topics-tag" href="/packages?q=topic%3Abackend" rel="nofollow">#backend</a></p><h3 class="title">Documentation</h3><p><a class="link" href="/documentation/shelf/latest/">API reference</a><br/></p><h3 class="title">License</h3><p><img class="inline-icon-img filter-invert-on-dark" src="/static/hash-v0koh7hq/img/material-icon-balance.svg" alt="" width="14" height="14" role="presentation"/>BSD-3-Clause (<a href="/packages/shelf/license">license</a>)</p><h3 class="title">Dependencies</h3><p><a href="/packages/async" title="^2.5.0">async</a>, <a href="/packages/collection" title="^1.15.0">collection</a>, <a href="/packages/http_parser" title="^4.1.0">http_parser</a>, <a href="/packages/path" title="^1.8.0">path</a>, <a href="/packages/stack_trace" title="^1.10.0">stack_trace</a>, <a href="/packages/stream_channel" title="^2.1.0">stream_channel</a></p><h3 class="title">More</h3><p><a href="/packages?q=dependency%3Ashelf" rel="nofollow">Packages that depend on shelf</a></p></div><p class="detail-lead-back"><a class="detail-metadata-toggle">Back</a></p></div><div id="-screenshot-carousel" class="carousel"><fab id="-carousel-prev" class="mdc-fab carousel-prev carousel-nav" data-mdc-auto-init="MDCRipple" title="Previous" data-ga-click-event="screenshot-carousel-prev-click" tabindex="0"><div class="mdc-fab__ripple"></div><img class="mdc-fab__icon" src="/static/hash-v0koh7hq/img/keyboard_arrow_left.svg" alt="previous" width="24" height="24" aria-hidden="true"/></fab><div id="-image-container" class="image-container"></div><fab id="-carousel-next" class="mdc-fab carousel-next carousel-nav" data-mdc-auto-init="MDCRipple" title="Next" data-ga-click-event="screenshot-carousel-next-click" tabindex="0"><div class="mdc-fab__ripple"></div><img class="mdc-fab__icon" src="/static/hash-v0koh7hq/img/keyboard_arrow_right.svg" alt="next" width="24" height="24" aria-hidden="true"/></fab><p id="-screenshot-description" class="screenshot-description"></p></div></main><footer class="site-footer"><a class="link" href="https://dart.dev/">Dart language</a><a class="link sep" href="/report?subject=package%3Ashelf&url=https%3A%2F%2Fpub.dev%2Fpackages%2Fshelf">Report package</a><a class="link sep" href="/policy">Policy</a><a class="link sep" href="https://www.google.com/intl/en/policies/terms/">Terms</a><a class="link sep" href="https://developers.google.com/terms/">API Terms</a><a class="link sep" href="/security">Security</a><a class="link sep" href="https://www.google.com/intl/en/policies/privacy/">Privacy</a><a class="link sep" href="/help">Help</a><a class="link icon sep" href="/feed.atom"><img class="inline-icon" src="/static/hash-v0koh7hq/img/rss-feed-icon.svg" alt="RSS" width="20" height="20" title="RSS/atom feed"/></a><a class="link icon github_issue" href="https://github.com/dart-lang/pub-dev/issues/new"><img class="inline-icon" src="/static/hash-v0koh7hq/img/bug-report-white-96px.png" alt="bug report" width="20" height="20" title="Report an issue with this site"/></a></footer><script src="/static/hash-v0koh7hq/highlight/highlight-with-init.js" defer="defer"></script></body></html>