### Basic Routing Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/router.md Demonstrates setting up simple GET and POST routes, as well as routes with path parameters. ```APIDOC ## Basic Routing ### Description Sets up simple GET and POST routes, and routes that capture parameters from the URL path. ### Method - `router.get(String route, Handler handler)` - `router.post(String route, Handler handler)` ### Endpoint - `/` (GET) - `/about` (GET) - `/users/` (GET) - `/users` (POST) ### Parameters #### Path Parameters - `id` (String) - The identifier for the user. ### Request Example ```dart // POST /users // Body: "user data" ``` ### Response #### Success Response (200) - `Response.ok('Home')` for GET / - `Response.ok('About')` for GET /about - `Response.ok('User: $id')` for GET /users/ - `Response.ok('Created user: $body')` for POST /users ``` -------------------------------- ### Basic Routing Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/router.md Demonstrates setting up simple GET and POST routes, as well as routes with parameters. Ensure you have the necessary shelf and shelf_router packages imported. ```dart import 'package:shelf_router/shelf_router.dart'; import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as io; void main() async { final router = Router(); // Simple routes router.get('/', (Request request) => Response.ok('Home')); router.get('/about', (Request request) => Response.ok('About')); // Routes with parameters router.get('/users/', (Request request) { final id = request.params['id']; return Response.ok('User: $id'); }); // POST handler router.post('/users', (Request request) async { final body = await request.readAsString(); return Response.ok('Created user: $body'); }); await io.serve(router, 'localhost', 8080); } ``` -------------------------------- ### Basic Shelf Router Setup and Route Configuration Source: https://github.com/dart-lang/shelf/blob/master/pkgs/shelf_router/README.md Instantiate a Router, define GET routes with and without parameters, and add it to a Shelf Pipeline with middleware. This example demonstrates the fundamental usage of shelf_router for handling web requests. ```dart import 'package:shelf_router/shelf_router.dart'; import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as io; // instantiate a router and configure your routes var router = Router(); router.get('/hello', (Request request) { return Response.ok('hello-world'); }); router.get('/user/', (Request request, String user) { return Response.ok('hello $user'); }); // use a Pipeline to configure your middleware, // then add the router as the handler final app = const Pipeline() .addMiddleware(logRequests()) .addHandler(router); var server = await io.serve(app, 'localhost', 8080); ``` -------------------------------- ### Basic WebSocket Handler Example Source: https://github.com/dart-lang/shelf/blob/master/pkgs/shelf_web_socket/README.md This example demonstrates how to set up a basic WebSocket handler using shelf_web_socket. It echoes messages back to the client and starts a server on localhost:8080. ```dart import 'package:shelf/shelf_io.dart' as shelf_io; import 'package:shelf_web_socket/shelf_web_socket.dart'; void main() { var handler = webSocketHandler((webSocket, _) { webSocket.stream.listen((message) { webSocket.sink.add('echo $message'); }); }); shelf_io.serve(handler, 'localhost', 8080).then((server) { print('Serving at ws://${server.address.host}:${server.port}'); }); } ``` -------------------------------- ### Basic Proxy Server Example Source: https://github.com/dart-lang/shelf/blob/master/pkgs/shelf_proxy/README.md Starts a local server that proxies all requests to dart.dev. Ensure you have the shelf and shelf_proxy packages added to your pubspec.yaml. ```dart import 'package:shelf/shelf_io.dart' as shelf_io; import 'package:shelf_proxy/shelf_proxy.dart'; void main() async { var server = await shelf_io.serve( proxyHandler("https://dart.dev"), 'localhost', 8080, ); print('Proxying at http://${server.address.host}:${server.port}'); } ``` -------------------------------- ### ShelfTestHandler expect() Usage Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/test-handler.md Provides an example of using the expect() method to define a GET request for '/api/users' and a POST request for '/api/users'. This demonstrates how to set up multiple expectations for different HTTP methods and paths. ```dart final testHandler = ShelfTestHandler(); testHandler.expect('GET', '/api/users', (request) { return Response.ok('[]'); }); testHandler.expect('POST', '/api/users', (request) async { final body = await request.readAsString(); return Response.ok('Created: $body'); }); ``` -------------------------------- ### Start an HTTP Server with a Shelf Handler Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/shelf-io.md Use `serve` to start an HttpServer listening on a specified address and port, routing requests to a Shelf handler. This is suitable for typical server applications. ```dart import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as io; void main() async { final handler = (Request request) => Response.ok('Hello, World!'); final server = await io.serve(handler, 'localhost', 8080); print('Serving at http://${server.address.host}:${server.port}'); } ``` -------------------------------- ### Basic Production Setup Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/README.md Sets up a production server with routing for API and static file serving. ```dart import 'package:shelf_router/shelf_router.dart'; import 'package:shelf_static/shelf_static.dart'; import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as io; void main() async { final api = Router() ..get('/api/status', (request) => Response.ok('OK')); final static = createStaticHandler('web', defaultDocument: 'index.html'); final handler = Cascade() .add(api) .add(static) .add((request) => Response.notFound('Not found')) .handler; final server = await io.serve(handler, '0.0.0.0', 8080); print('Server running on ${server.address.host}:${server.port}'); } ``` -------------------------------- ### Start HTTP Server Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/README.md Starts a basic HTTP server using the provided handler, host, and port. ```dart await serve(handler, 'localhost', 8080); ``` -------------------------------- ### Basic Handler Testing Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/test-handler.md Demonstrates basic testing of a Shelf handler using ShelfTestHandler. It sets up an expectation for a GET request to '/api/status' and verifies that the handler returns a non-null response. ```dart import 'package:shelf/shelf.dart'; import 'package:shelf_test_handler/shelf_test_handler.dart'; import 'package:test/test.dart'; void main() { test('handler returns correct response', () { final testHandler = ShelfTestHandler(); testHandler.expect('GET', '/api/status', (request) { return Response.ok('OK'); }); final request = Request('GET', Uri.parse('http://localhost/api/status')); final response = testHandler(request); expect(response, isNotNull); }); } ``` -------------------------------- ### Start HTTPS Server Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/README.md Starts an HTTPS server with optional security context for TLS. ```dart await serve(handler, 'localhost', 8443, securityContext: context); ``` -------------------------------- ### Create a Simple HTTP Server Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/README.md This example demonstrates how to create a basic HTTP server that responds with 'Hello, World!' to all requests. ```dart import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as io; void main() async { final handler = (Request request) => Response.ok('Hello, World!'); await io.serve(handler, 'localhost', 8080); } ``` -------------------------------- ### Chat Server Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/websocket-handler.md A full-featured chat server example demonstrating broadcasting messages to all connected WebSocket clients. Manages a list of active connections. ```dart import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as io; import 'package:shelf_web_socket/shelf_web_socket.dart'; final connections = []; void main() async { final handler = webSocketHandler((channel, protocol) { connections.add(channel); print('Client connected. Total: ${connections.length}'); channel.stream.listen( (message) { // Broadcast message to all connected clients for (var client in connections) { client.sink.add(message); } }, onError: (error) { print('Error: $error'); }, onDone: () { connections.remove(channel); print('Client disconnected. Total: ${connections.length}'); }, ); }); await io.serve(handler, 'localhost', 8080); } ``` -------------------------------- ### Create HTTPS Server with shelf_io Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/shelf-io.md Shows how to configure and start an HTTPS server using `shelf_io`. Requires loading a certificate and private key into a `SecurityContext`. ```dart import 'dart:io'; import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as io; void main() async { final context = SecurityContext.defaultContext; // Load certificate and key context.useCertificateChain('path/to/cert.pem'); context.usePrivateKey('path/to/key.pem'); final handler = (Request request) => Response.ok('Hello, World!'); final server = await io.serve( handler, 'localhost', 8443, securityContext: context, ); print('Serving at https://${server.address.host}:${server.port}'); } ``` -------------------------------- ### Basic Static File Server Setup Source: https://github.com/dart-lang/shelf/blob/master/pkgs/shelf_static/README.md Sets up a basic static file server using shelf_static. Serves files from the 'example/files' directory and uses 'index.html' as the default document. ```dart import 'package:shelf/shelf_io.dart' as io; import 'package:shelf_static/shelf_static.dart'; void main() { var handler = createStaticHandler('example/files', defaultDocument: 'index.html'); io.serve(handler, 'localhost', 8080); } ``` -------------------------------- ### HTTPS Production Setup Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/README.md Configures an HTTPS server with certificate and private key for secure connections. ```dart import 'dart:io'; void main() async { final context = SecurityContext.defaultContext; context.useCertificateChain('cert.pem'); context.usePrivateKey('key.pem'); final handler = myHandler; final server = await serve(handler, '0.0.0.0', 8443, securityContext: context); print('HTTPS server on ${server.address.host}:${server.port}'); } ``` -------------------------------- ### Create an HTTP Server with Routing Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/README.md This example shows how to set up an HTTP server with routing using shelf_router. It defines routes for the home page and dynamic user IDs. ```dart import 'package:shelf_router/shelf_router.dart'; import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as io; void main() async { final router = Router() ..get('/', (Request request) => Response.ok('Home')) ..get('/users/', (Request request) { final id = request.params['id']; return Response.ok('User: $id'); }); await io.serve(router, 'localhost', 8080); } ``` -------------------------------- ### Nested Routes Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/endpoints.md Demonstrates how to mount routers to create nested routing structures, organizing endpoints by resource. ```APIDOC ## GET /api/users ### Description Lists all users. ### Method GET ### Endpoint /api/users ## GET /api/users/ ### Description Retrieves a specific user by ID. ### Method GET ### Endpoint /api/users/ #### Path Parameters - **id** (string) - Required - The user's unique identifier. ## POST /api/users ### Description Creates a new user. ### Method POST ### Endpoint /api/users ## PUT /api/users/ ### Description Updates an existing user. ### Method PUT ### Endpoint /api/users/ #### Path Parameters - **id** (string) - Required - The user's unique identifier. ## DELETE /api/users/ ### Description Deletes a user. ### Method DELETE ### Endpoint /api/users/ #### Path Parameters - **id** (string) - Required - The user's unique identifier. ## GET /api/status ### Description Retrieves the system status. ### Method GET ### Endpoint /api/status ``` -------------------------------- ### serve() Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/shelf-io.md Starts an HttpServer listening on the specified address and port, routing all requests to the provided handler. This function is used to run a Shelf handler as a standalone HTTP server. ```APIDOC ## serve() ### Description Starts an `HttpServer` listening on the specified address and port, routing all requests to the provided handler. ### Method `Future serve( Handler handler, Object address, int port, { SecurityContext? securityContext, int? backlog, bool shared = false, String? poweredByHeader = 'Dart with package:shelf', } )` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **handler** (Handler) - Required - The Shelf handler to process requests - **address** (Object) - Required - The address to bind to (string hostname or InternetAddress) - **port** (int) - Required - The port to listen on - **securityContext** (SecurityContext) - Optional - For HTTPS; if provided, starts an HTTPS server - **backlog** (int) - Optional - The socket backlog size (max pending connections) - **shared** (bool) - Optional - Whether multiple processes can bind the same address/port - **poweredByHeader** (String) - Optional - The X-Powered-By header value; pass null to omit ### Returns A `Future` that completes when the server is listening ### Header Defaults - Every response gets a "date" header automatically added (if not present) - Every response gets an "X-Powered-By" header (if not present) ### Request Example ```dart import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as io; void main() async { final handler = (Request request) => Response.ok('Hello, World!'); final server = await io.serve(handler, 'localhost', 8080); print('Serving at http://${server.address.host}:${server.port}'); } ``` ``` -------------------------------- ### Conditional Routes Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/endpoints.md Illustrates how to define routes that conditionally match based on the presence of query parameters. ```APIDOC ## GET /search?q= ### Description Performs a search based on the provided query parameter. If the 'q' query parameter is not present, this route will not match. ### Method GET ### Endpoint /search #### Query Parameters - **q** (string) - Required - The search query. ### Response #### Success Response (200) - (string) - Search results or a message indicating the search query. ## GET /search (Fallback) ### Description Serves a search form if no 'q' query parameter is provided to the /search endpoint. ### Method GET ### Endpoint /search ### Response #### Success Response (200) - (string) - HTML content for the search form. ### Response Example ```html
...
``` ``` -------------------------------- ### Testing Request Headers Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/test-handler.md Illustrates how to test a handler that validates request headers, specifically the 'authorization' header. It sets up an expectation for a GET request to '/protected' and checks for the presence and value of the authorization header. ```dart test('handler validates auth headers', () { final testHandler = ShelfTestHandler(); testHandler.expect('GET', '/protected', (request) { final auth = request.headers['authorization']; if (auth == null) { return Response.unauthorized('Missing auth'); } return Response.ok('Protected data'); }); final request = Request( 'GET', Uri.parse('http://localhost/protected'), headers: {'authorization': 'Bearer token123'}, ); final response = testHandler(request); expect(response.statusCode, equals(200)); }); ``` -------------------------------- ### Serve HTTP Requests with Shelf Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/configuration.md Use the serve function to start an HTTP server, binding to a specified address and port. Configure security context, backlog, sharing, and the poweredByHeader. ```dart Future serve( Handler handler, Object address, int port, { SecurityContext? securityContext, int? backlog, bool shared = false, String? poweredByHeader = 'Dart with package:shelf', } ) ``` -------------------------------- ### Route Matching Order Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/router.md Demonstrates that the first registered route for a given path and method is used. Subsequent routes with the same path and method are not matched. ```dart final router = Router(); // This route matches FIRST router.get('/items', (request) => Response.ok('All items')); // This route would never match for /items router.get('/items', (request) => Response.ok('Specific items')); ``` -------------------------------- ### Required File Header Source: https://github.com/dart-lang/shelf/blob/master/CONTRIBUTING.md All files in the project must start with this copyright and license header. ```dart // Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. ``` -------------------------------- ### Create an HTTP Server with Middleware Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/README.md This example demonstrates adding middleware to an HTTP server for request logging. The `createMiddleware` function is used to define custom middleware. ```dart import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as io; void main() async { final handler = (Request request) => Response.ok('Hello'); final logMiddleware = createMiddleware( requestHandler: (request) { print('${request.method} ${request.url}'); return null; }, ); final app = logMiddleware(handler); await io.serve(app, 'localhost', 8080); } ``` -------------------------------- ### Run Full Compliance Test Suite Source: https://github.com/dart-lang/shelf/blob/master/pkgs/_shelf_compliance/README.md Execute the entire suite of HTTP/1.1 compliance and hardening tests for package:shelf. Ensure the .NET 10 SDK is installed before running. ```bash dart test ``` -------------------------------- ### Create a 200 OK response Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/response.md Example of creating a simple 200 OK response with plain text. ```dart import 'package:shelf/shelf.dart'; // Simple 200 OK Handler okHandler(Request request) { return Response.ok('Hello, World!'); } ``` -------------------------------- ### Redirect Responses Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/response.md Examples for creating temporary and permanent redirect responses. ```APIDOC ## Redirects ### Temporary Redirect (Found) ```dart Handler redirectHandler(Request request) { return Response.found('/new-location'); } ``` ### Permanent Redirect (Moved Permanently) ```dart Handler permanentRedirectHandler(Request request) { return Response.movedPermanently('https://example.com/new'); } ``` ``` -------------------------------- ### Basic Response Creation Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/response.md Examples of creating basic HTTP responses with different status codes. ```APIDOC ## Basic Responses ### Simple 200 OK ```dart Handler okHandler(Request request) { return Response.ok('Hello, World!'); } ``` ### 404 Not Found ```dart Handler notFoundHandler(Request request) { return Response.notFound('Resource not found'); } ``` ### 500 Internal Server Error ```dart Handler errorHandler(Request request) { return Response.internalServerError(body: 'Something went wrong'); } ``` ``` -------------------------------- ### Create an empty Pipeline Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/pipeline-and-cascade.md Initializes a new, empty pipeline. This is the starting point for adding middleware and handlers. ```dart const Pipeline() ``` -------------------------------- ### Test Path Parameters with ShelfTestHandler Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/test-handler.md Demonstrates how to test handlers that expect path parameters. This example defines a route with a parameter and verifies the handler's response. ```dart test('handler with path parameters', () { final testHandler = ShelfTestHandler(); testHandler.expect('GET', '/users/123', (request) { return Response.ok('User 123'); }); final response = testHandler( Request('GET', Uri.parse('http://localhost/users/123')) ); expect(response.statusCode, equals(200)); }); ``` -------------------------------- ### Create a response with custom headers Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/response.md Example demonstrating how to set custom headers, such as 'content-type' and a custom header like 'x-custom-header', when creating a response. ```dart Handler customHeaderHandler(Request request) { return Response.ok( 'JSON content', headers: { 'content-type': 'application/json', 'x-custom-header': 'value', }, ); } ``` -------------------------------- ### Serve All Packages with Default Resolution Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/packages-handler.md Uses the current isolate's package resolution to serve all packages. This is a common setup for serving package assets. ```dart import 'package:shelf_packages_handler/shelf_packages_handler.dart'; import 'package:shelf/shelf_io.dart' as io; void main() async { // Uses the current isolate's package resolution final handler = packagesHandler(); await io.serve(handler, 'localhost', 8080); // GET /shelf/lib/shelf.dart serves the shelf package // GET /shelf_router/lib/shelf_router.dart serves shelf_router } ``` -------------------------------- ### Content Negotiation Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/endpoints.md Endpoints can return different content based on the `Accept` header. This example shows how to return JSON or XML based on the requested format. ```APIDOC ## Content Negotiation Endpoints can return different content based on Accept header: ```dart router.get('/data/', (request) { final format = request.params['format']; if (format == 'json') { return Response.ok(jsonEncode(data), headers: {'content-type': 'application/json'}); } else if (format == 'xml') { return Response.ok(xmlEncode(data), headers: {'content-type': 'application/xml'}); } else { return Response.notFound('Format not supported'); } }); // Requests: // GET /data/json -> returns JSON // GET /data/xml -> returns XML // GET /data/yaml -> returns 404 ``` ``` -------------------------------- ### Responses with Custom Headers Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/response.md Example of creating a response with custom headers, including content type. ```APIDOC ## Responses with Headers ```dart Handler customHeaderHandler(Request request) { return Response.ok( 'JSON content', headers: { 'content-type': 'application/json', 'x-custom-header': 'value', }, ); } ``` ``` -------------------------------- ### API Gateway with Shelf Router Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/proxy-handler.md Set up an API gateway by mounting different proxy handlers to specific routes using shelf_router. This example routes requests for /users, /products, and /orders to their respective services. ```dart import 'package:shelf/shelf.dart'; import 'package:shelf_router/shelf_router.dart'; import 'package:shelf_proxy/shelf_proxy.dart'; // Services behind the gateway final userServiceProxy = proxyHandler('http://users:3000'); final productServiceProxy = proxyHandler('http://products:3000'); final orderServiceProxy = proxyHandler('http://orders:3000'); final gateway = Router() ..mount('/users', userServiceProxy) ..mount('/products', productServiceProxy) ..mount('/orders', orderServiceProxy) ..all('/', (request) => Response.notFound('Service not found')); await io.serve(gateway, 'localhost', 8080); ``` -------------------------------- ### Simple Shelf Handler Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/middleware-and-handlers.md A basic Shelf handler that processes a request and returns a simple OK response. This serves as a fundamental building block for Shelf applications. ```dart import 'package:shelf/shelf.dart'; Handler simpleHandler(Request request) async { return Response.ok('Hello from Shelf!'); } ``` -------------------------------- ### JSON Responses Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/response.md Example of creating a JSON response, ensuring the correct content type header is set. ```APIDOC ## JSON Responses ```dart import 'dart:convert'; Handler jsonHandler(Request request) { final data = {'message': 'Hello', 'status': 200}; return Response.ok( jsonEncode(data), headers: {'content-type': 'application/json'}, ); } ``` ``` -------------------------------- ### Create a 404 Not Found response Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/response.md Example of creating a 404 Not Found response, typically used when a requested resource does not exist. ```dart import 'package:shelf/shelf.dart'; // 404 Not Found Handler notFoundHandler(Request request) { return Response.notFound('Resource not found'); } ``` -------------------------------- ### ShelfTestHandler expectAnything() Usage Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/test-handler.md Illustrates the usage of expectAnything() in conjunction with expect(). It shows how to define a specific expectation for '/users' and then use expectAnything() to handle any subsequent requests. ```dart final testHandler = ShelfTestHandler(); testHandler.expect('GET', '/users', usersHandler); testHandler.expectAnything(handleAnything); // Accepts any request after /users ``` -------------------------------- ### RESTful API Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/endpoints.md Defines common RESTful API endpoints for managing users, including listing, retrieving, creating, updating, patching, and deleting users. ```APIDOC ## GET /api/users ### Description Retrieves a list of all users. ### Method GET ### Endpoint /api/users ### Response #### Success Response (200) - users (List) - A list of user objects. ### Request Example ```json {} ``` ### Response Example ```json [ { "id": "1", "name": "John Doe" } ] ``` ## GET /api/users/ ### Description Retrieves a single user by their ID. ### Method GET ### Endpoint /api/users/ #### Path Parameters - **id** (string) - Required - The unique identifier of the user. ### Response #### Success Response (200) - (User) - The user object. ### Request Example ```json {} ``` ### Response Example ```json { "id": "1", "name": "John Doe" } ``` ## POST /api/users ### Description Creates a new user. ### Method POST ### Endpoint /api/users #### Request Body - (User) - The user object to create. ### Request Example ```json { "name": "Jane Doe" } ``` ### Response #### Success Response (200) - (User) - The newly created user object. ### Response Example ```json { "id": "2", "name": "Jane Doe" } ``` ## PUT /api/users/ ### Description Replaces an existing user with new data. ### Method PUT ### Endpoint /api/users/ #### Path Parameters - **id** (string) - Required - The unique identifier of the user to update. #### Request Body - (User) - The updated user object. ### Request Example ```json { "name": "Jane Smith" } ``` ### Response #### Success Response (200) - (User) - The updated user object. ### Response Example ```json { "id": "2", "name": "Jane Smith" } ``` ## PATCH /api/users/ ### Description Partially updates an existing user. ### Method PATCH ### Endpoint /api/users/ #### Path Parameters - **id** (string) - Required - The unique identifier of the user to patch. #### Request Body - (User) - An object containing the fields to update. ### Request Example ```json { "name": "Jane A. Smith" } ``` ### Response #### Success Response (200) - (User) - The partially updated user object. ### Response Example ```json { "id": "2", "name": "Jane A. Smith" } ``` ## DELETE /api/users/ ### Description Deletes a user by their ID. ### Method DELETE ### Endpoint /api/users/ #### Path Parameters - **id** (string) - Required - The unique identifier of the user to delete. ### Response #### Success Response (200) - (string) - A confirmation message indicating the user was deleted. ### Response Example ``` User deleted ``` ``` -------------------------------- ### Shelf Handler with Path Routing Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/middleware-and-handlers.md An example of a handler that implements basic path routing. It inspects the request URL to determine the appropriate response for different paths. ```dart Handler routingHandler(Request request) async { if (request.url.path.startsWith('api/')) { return Response.ok('API response'); } else if (request.url.path.startsWith('public/')) { return Response.ok('Public response'); } return Response.notFound('Not found'); } ``` -------------------------------- ### Query Parameter Handling Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/endpoints.md Query parameters can be accessed from the request URI. This example shows how to retrieve a search query and a limit parameter. ```APIDOC ## Query Parameter Handling ```dart router.get('/search', (request) { final query = request.uri.queryParameters['q'] ?? ''; final limit = int.tryParse( request.uri.queryParameters['limit'] ?? '10' ) ?? 10; return Response.ok('Search: $query (limit: $limit)'); }); // Requests: // GET /search?q=test -> search for 'test', limit 10 // GET /search?q=test&limit=50 -> search for 'test', limit 50 ``` ``` -------------------------------- ### Create Middleware for Error Handling Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/middleware-and-handlers.md Handle errors gracefully with `createMiddleware` and `errorHandler`. This example logs errors and returns specific `Response` objects for `FormatException` or other internal server errors. ```dart final errorHandlingMiddleware = createMiddleware( errorHandler: (error, stackTrace) { print('Error: $error\n$stackTrace'); if (error is FormatException) { return Response.badRequest(body: 'Invalid format: ${error.message}'); } return Response.internalServerError( body: 'An unexpected error occurred', ); }, ); ``` -------------------------------- ### Testing Sequential HTTP Requests with ShelfTestHandler Source: https://github.com/dart-lang/shelf/blob/master/pkgs/shelf_test_handler/README.md Demonstrates how to use ShelfTestHandler to define expected HTTP requests and their responses for testing client-server interactions. This snippet sets up a handler to expect a GET request to /token and defines how to respond to it. ```dart import 'package:shelf/shelf.dart' as shelf; import 'package:shelf_test_handler/shelf_test_handler.dart'; import 'package:test/test.dart'; import 'package:my_package/my_package.dart'; void main() { test("client performs protocol handshake", () async { // This is just a utility class that starts a server for a ShelfTestHandler. var server = new ShelfTestServer(); // Asserts that the client will make a GET request to /token. server.handler.expect("GET", "/token", (request) async { // This handles the GET /token request. var body = JSON.parse(await request.readAsString()); // Any failures in this handler will cause the test to fail, so it's safe // to make assertions. expect(body, containsPair("id", "my_package_id")); expect(body, containsPair("secret", "123abc")); return new shelf.Response.ok(JSON.encode({"token": "a1b2c3"}), headers: {"content-type": "application/json"}); }); // Requests made against `server.url` will be handled by the handlers we // declare. var myPackage = new MyPackage(server.url); // If the client makes any unexpected requests, the test will fail. await myPackage.performHandshake(); }); } ``` -------------------------------- ### Handle conditional GET requests with If-Modified-Since Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/response.md Example demonstrating how to handle conditional GET requests using the `If-Modified-Since` header. If the resource has not been modified since the specified date, a `304 Not Modified` response is returned. ```dart Handler conditionalHandler(Request request) { final lastModified = DateTime(2024, 1, 1); if (request.ifModifiedSince != null && request.ifModifiedSince!.isAfter(lastModified)) { return Response.notModified(); } return Response.ok( 'Content', headers: { 'last-modified': lastModified.toString(), 'cache-control': 'max-age=3600', }, ); } ``` -------------------------------- ### Conditional Routing Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/router.md Demonstrates using `Router.routeNotFound` to conditionally match routes. If a condition is not met, returning `Router.routeNotFound` allows the next route definition to be evaluated. ```dart final router = Router(); // Handler that conditionally matches based on query parameters router.get('/search', (Request request) { if (!request.uri.queryParameters.containsKey('q')) { return Router.routeNotFound; // Try next route } return Response.ok('Search results'); }); // Fallback route router.get('/search', (Request request) { return Response.ok('Search form'); }); ``` -------------------------------- ### Testing Request Body Handling Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/test-handler.md Shows how to test a handler that processes POST requests with a request body. It defines an expectation for a POST request to '/api/users', reads the body, and verifies the response. ```dart test('handler processes POST body', () async { final testHandler = ShelfTestHandler(); testHandler.expect('POST', '/api/users', (request) async { final body = await request.readAsString(); return Response.ok('User: $body'); }); final request = Request( 'POST', Uri.parse('http://localhost/api/users'), body: '{"name":"Alice"}', ); final response = await testHandler(request); expect(response.statusCode, equals(200)); }); ``` -------------------------------- ### Configure CORS Middleware in Shelf Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/endpoints.md Apply CORS middleware to handle Cross-Origin Resource Sharing. This example sets common CORS headers to allow requests from any origin. ```dart final corsMiddleware = createMiddleware( responseHandler: (response) { return response.change( headers: { 'access-control-allow-origin': '*', 'access-control-allow-methods': 'GET,POST,PUT,DELETE', 'access-control-allow-headers': 'Content-Type', }, ); }, ); final handler = corsMiddleware(router); ``` -------------------------------- ### Invalid Handler Path Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/errors.md Providing a handlerPath that is not root-relative (i.e., does not start with '/') to the Request constructor will throw an ArgumentError. Ensure handler paths are correctly formatted. ```dart // Throws ArgumentError - doesn't start with / Request('GET', Uri.parse('http://localhost/api'), handlerPath: 'api/'); ``` -------------------------------- ### Basic Shelf Web Server with Request Logging Source: https://github.com/dart-lang/shelf/blob/master/pkgs/shelf/README.md This snippet demonstrates setting up a basic Shelf web server that logs incoming requests and echoes the request URL back to the client. It uses a Pipeline to add the logRequests middleware and a simple handler to echo the request. ```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}"'); ``` -------------------------------- ### Create Static File Handler with Custom ETag Generation Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/static-file-handler.md Demonstrates disabling ETag generation by returning null, and provides an example of a custom ETag generator based on file path hash and size for cache validation. ```dart // Disable ETag generation final handler = createStaticHandler( 'public', generateETag: (file, stat) => null, ); // Custom ETag based on file name and size final customHandler = createStaticHandler( 'public', generateETag: (file, stat) async { return '${file.path.hashCode}-${stat.size}'; }, ); ``` -------------------------------- ### Conditional GET with If-Modified-Since Header Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/request.md Implements conditional GET logic by checking the If-Modified-Since header against a resource's last modified date. ```dart Handler conditionalGet(Request request) async { final lastModified = DateTime(2024, 1, 1); if (request.ifModifiedSince != null && request.ifModifiedSince!.isAfter(lastModified)) { return Response.notModified(); } return Response.ok('Content', headers: {'last-modified': lastModified.toString()}); } ``` -------------------------------- ### Basic WebSocket Server Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/websocket-handler.md Sets up a basic WebSocket server that echoes messages back to the client. Requires shelf and shelf_web_socket packages. ```dart import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as io; import 'package:shelf_web_socket/shelf_web_socket.dart'; void main() async { final handler = webSocketHandler((channel, protocol) { // Handle incoming messages channel.stream.listen((message) { // Echo the message back channel.sink.add('Echo: $message'); }); }); await io.serve(handler, 'localhost', 8080); } ``` -------------------------------- ### Routing Middleware Example Source: https://github.com/dart-lang/shelf/blob/master/pkgs/shelf/README.md This example illustrates how a routing middleware would update the request's handlerPath and url when forwarding a request to an inner handler. It uses Request.change() to modify the request path. ```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)); ``` -------------------------------- ### Registering HTTP Verb Routes Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/router.md Use these methods to register specific handlers for HTTP methods like GET, POST, PUT, DELETE, etc. A special behavior for GET automatically registers a HEAD handler that removes the response body. ```dart void get(String route, Function handler) void head(String route, Function handler) void post(String route, Function handler) void put(String route, Function handler) void delete(String route, Function handler) void patch(String route, Function handler) void options(String route, Function handler) void connect(String route, Function handler) void trace(String route, Function handler) ``` -------------------------------- ### HTTP Verb Methods Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/router.md Register handlers for specific HTTP methods (GET, HEAD, POST, PUT, DELETE, PATCH, OPTIONS, CONNECT, TRACE). The `GET` method has a special behavior where it automatically registers a `HEAD` handler that omits the response body. ```APIDOC ## HTTP Verb Methods ### Description Register handlers for specific HTTP methods. ### Methods - `get(String route, Function handler)` - `head(String route, Function handler)` - `post(String route, Function handler)` - `put(String route, Function handler)` - `delete(String route, Function handler)` - `patch(String route, Function handler)` - `options(String route, Function handler)` - `connect(String route, Function handler)` - `trace(String route, Function handler)` ### Parameters - **route** (String) - Required - Path pattern (e.g., `/users/`) - **handler** (Function) - Required - Handler function or method ### Special Behavior for GET Automatically registers a HEAD handler that removes the response body. ``` -------------------------------- ### Enable HTTPS in Shelf Server Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/configuration.md Configure the SecurityContext with your certificate and private key paths, then pass it to the serve function to enable HTTPS. ```dart final context = SecurityContext.defaultContext; context.useCertificateChain('path/to/cert.pem'); context.usePrivateKey('path/to/key.pem'); await serve(handler, 'localhost', 8443, securityContext: context); ``` -------------------------------- ### Streaming Responses Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/response.md Example of creating a response with a streaming body. ```APIDOC ## Streaming Responses ```dart Handler streamHandler(Request request) async { final data = Stream.fromIterable([ [1, 2, 3], [4, 5, 6], ]); return Response.ok(data); } ``` ``` -------------------------------- ### Request.method Property Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/request.md Accesses the HTTP method of the request, such as 'GET' or 'POST'. ```dart final String method ``` -------------------------------- ### Response Modification Example Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/response.md Demonstrates modifying an existing response using the `change` method. ```APIDOC ## Response Modification ```dart Handler modifyHandler(Request request) { var response = Response.ok('Original'); // Add headers to existing response response = response.change( headers: {'x-processed': 'true'}, ); return response; } ``` ``` -------------------------------- ### Response.notModified() Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/response.md Constructs a 304 Not Modified response. This is used for conditional GET requests when the resource has not changed. ```APIDOC ## Response.notModified() ### Description Constructs a 304 Not Modified response. Used for conditional GET requests where the resource hasn't changed. Content-Length header is automatically removed. ### Parameters #### Parameters - **headers** (Map?) - Optional - HTTP headers for the response. - **context** (Map?) - Optional - Extra context data for middleware. ``` -------------------------------- ### Encoding from Content-Type Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/request.md Gets the character encoding from the Content-Type charset parameter. Returns null if not set. ```dart Encoding? get encoding ``` -------------------------------- ### Conditional Responses (Not Modified) Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/response.md Example demonstrating how to handle conditional requests using the `If-Modified-Since` header. ```APIDOC ## Conditional Responses ```dart Handler conditionalHandler(Request request) { final lastModified = DateTime(2024, 1, 1); if (request.ifModifiedSince != null && request.ifModifiedSince!.isAfter(lastModified)) { return Response.notModified(); } return Response.ok( 'Content', headers: { 'last-modified': lastModified.toString(), 'cache-control': 'max-age=3600', }, ); } ``` ``` -------------------------------- ### Dynamic Package Discovery with pub cache Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/packages-handler.md Demonstrates how to dynamically discover packages from the pub cache and create a package map. Note that packagesHandler can also use the isolate's default resolution. ```dart import 'dart:io'; import 'package:shelf_packages_handler/shelf_packages_handler.dart'; void main() async { // Discover packages in pub cache final pubCacheDir = Directory(Platform.environment['PUB_CACHE']!); // Create package map from pub cache structure final packageMap = {}; // packagesHandler automatically uses current isolate's resolution final handler = packagesHandler(); await io.serve(handler, 'localhost', 8080); } ``` -------------------------------- ### Serve Static Files with Shelf Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/endpoints.md Mount a handler to serve static files from the filesystem under a specific URL prefix. Requests to paths within the prefix will be mapped to corresponding files. ```dart final router = Router() ..get('/api/data', apiHandler) ..mount('/static', staticFileHandler); // Requests: // GET /static/style.css -> serves style.css from filesystem // GET /static/js/app.js -> serves js/app.js from filesystem // GET /static/index.html -> serves index.html ``` -------------------------------- ### Serve API Routes and Packages with Cascade Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/packages-handler.md This snippet demonstrates how to combine API routes and package serving using Shelf's Cascade. It sets up a router for API endpoints and a handler for serving packages from the current directory, falling back to a 404 for unmatched requests. ```dart import 'package:shelf/shelf.dart'; import 'package:shelf_router/shelf_router.dart'; import 'package:shelf_packages_handler/shelf_packages_handler.dart'; import 'package:shelf/shelf_io.dart' as io; void main() async { // API routes final apiRouter = Router() ..get('/api/version', (request) => Response.ok('1.0.0')) ..get('/api/health', (request) => Response.ok('OK')); // Package serving for development final packages = packagesDirHandler(); // Serve both API and packages final handler = Cascade() .add(apiRouter) .add(packages) .add((request) => Response.notFound('Not found')) .handler; await io.serve(handler, 'localhost', 8080); } ``` -------------------------------- ### Create Basic Static File Handler Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/static-file-handler.md Creates a Shelf handler to serve files from a specified directory. This is the most basic usage for serving static assets. ```dart import 'package:shelf_static/shelf_static.dart'; import 'package:shelf/shelf_io.dart' as io; void main() async { final handler = createStaticHandler('public'); await io.serve(handler, 'localhost', 8080); } ``` -------------------------------- ### Content Length Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/request.md Gets the Content-Length header value parsed as an integer. Returns null if the header is not present. ```dart int? get contentLength ``` -------------------------------- ### Static File Serving Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/endpoints.md Serve static files by mounting `createStaticHandler`. Requests to paths like `/static/style.css` will serve the corresponding file from the filesystem. ```APIDOC ## Static File Serving Endpoints Static files are served by mounting `createStaticHandler`. ```dart final router = Router() ..get('/api/data', apiHandler) ..mount('/static', staticFileHandler); // Requests: // GET /static/style.css -> serves style.css from filesystem // GET /static/js/app.js -> serves js/app.js from filesystem // GET /static/index.html -> serves index.html ``` ``` -------------------------------- ### Response.seeOther() Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/response.md Constructs a 303 See Other response. This indicates that the response to the request should be retrieved using GET at a new URI. ```APIDOC ## Response.seeOther() ### Description Constructs a 303 See Other response indicating the response to the request should be retrieved using GET at a new URI. The `location` parameter is automatically set. ### Parameters #### Parameters - **location** (Object) - Required - The new URI for the response. - **body** (Object?) - Optional - The response body. - **headers** (Map?) - Optional - HTTP headers for the response. - **encoding** (Encoding?) - Optional - Encoding for string bodies; sets the Content-Type charset. Defaults to utf8. - **context** (Map?) - Optional - Extra context data for middleware. ``` -------------------------------- ### Create packagesHandler Source: https://github.com/dart-lang/shelf/blob/master/_autodocs/api-reference/packages-handler.md Creates a handler that serves package assets directly. It maps package URIs to filesystem or HTTP URLs, returning 404 for non-existent or unsupported schemes. ```dart import 'package:shelf_packages_handler/shelf_packages_handler.dart'; import 'package:shelf/shelf_io.dart' as io; void main() async { final handler = packagesHandler(); await io.serve(handler, 'localhost', 8080); // GET /angular/lib/angular.dart serves the angular package's asset } ```