Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
2337462
docs: Fix WebServer documentation to match actual implementation
nielsenko Nov 20, 2025
fd5b86d
docs: Add routing and middleware documentation
nielsenko Nov 20, 2025
69a2a83
docs: Add modular route documentation with injectIn override
nielsenko Nov 20, 2025
dbcd65e
docs: Add comprehensive ContextProperty documentation
nielsenko Nov 20, 2025
a70822f
docs: Add typed headers documentation
nielsenko Nov 20, 2025
094db22
docs: Add custom typed headers documentation
nielsenko Nov 20, 2025
7af9bde
docs: Add extension methods for custom typed headers
nielsenko Nov 20, 2025
205a0cd
docs: Clarify /** is tail-match wildcard with O(h) performance guarantee
nielsenko Nov 20, 2025
d1f65c3
docs: Clarify raw header access works for all headers, not just custo…
nielsenko Nov 20, 2025
0338cc5
docs: Update cache-busting documentation with CacheBustingConfig
nielsenko Nov 20, 2025
7b8141e
docs: Document automatic ETag and Last-Modified support in StaticRoute
nielsenko Nov 20, 2025
dba44cf
docs: Replace authentication examples with better ContextProperty use…
nielsenko Nov 20, 2025
9177dc8
docs: Replace authentication middleware with API key validation example
nielsenko Nov 20, 2025
4f89069
docs: Add critical clarifications for error handling and Session access
nielsenko Nov 20, 2025
a6a29fc
docs: Add error handling middleware section
nielsenko Nov 20, 2025
9ca1c25
docs: Add connecting prose to improve documentation flow
nielsenko Nov 20, 2025
c6c9451
docs: Rewrap webserver section
nielsenko Nov 20, 2025
7090f51
docs: Improve documentation based on feedback
nielsenko Nov 20, 2025
600201b
docs: Fix style issues in introduction
nielsenko Nov 20, 2025
377342b
docs: Fix code formatting broken by markdown rewrap
nielsenko Nov 20, 2025
4106f7e
docs: Rewrap with prettier (not zed)
nielsenko Nov 20, 2025
5097b11
docs: Fix hyphenation nit
nielsenko Nov 20, 2025
8060dad
docs: Use proper HTTP code blocks for conditional request examples
nielsenko Nov 20, 2025
36606c4
docs: Split WebServer documentation into multiple focused pages
nielsenko Nov 21, 2025
da476a0
docs: Use sequence diagram to explain middleware order
nielsenko Nov 21, 2025
c1a002e
docs: Nit. We are cannot generate REST apis (old mistake)
nielsenko Nov 21, 2025
be7dc48
docs: Fix lints
nielsenko Nov 21, 2025
fee2c6d
fix: Don't use title casing for titles or labels
nielsenko Nov 24, 2025
60caaf2
fix: Remove Web server from getting started section again
nielsenko Nov 24, 2025
84d8877
fix: Move modular routes as a subsection of routing
nielsenko Nov 24, 2025
211dadd
fix: Slim down typed headers section
nielsenko Nov 24, 2025
d1cd794
fix: Drop modular route example (belongs in Relic)
nielsenko Nov 24, 2025
eee902d
fix: Reduce size of module example
nielsenko Nov 24, 2025
60a663a
fix: Some re-ordering
nielsenko Nov 24, 2025
9e6cc38
fix: maxAge is now a Duration. Remove overlooked duplicated section
nielsenko Nov 24, 2025
0a874fb
fix: Prefer next over innerHandler for consistency
nielsenko Nov 24, 2025
37029a8
ci: lint stuff
nielsenko Nov 24, 2025
2cd9649
fix: Talk about why fallback and /** is not the same
nielsenko Nov 24, 2025
826bd8f
fix: Remove stale links to modular-routes
nielsenko Nov 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 0 additions & 74 deletions docs/06-concepts/18-webserver.md

This file was deleted.

153 changes: 153 additions & 0 deletions docs/06-concepts/18-webserver/01-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Overview

In addition to the application server, Serverpod comes with a built-in web server. The web server allows you to access your database and business layer the same way you would from a method call from an app. This makes it simple to share data for applications that need both an app and traditional web pages. You can also use the web server to create webhooks or define custom REST APIs to communicate with third-party services.

Serverpod's web server is built on the [Relic](https://github.com/serverpod/relic) framework, giving you access to its routing engine, middleware system, and typed headers. This means you get the benefits of Serverpod's database integration and business logic alongside Relic's web server capabilities.

## Your first route

When you create a new Serverpod project, it sets up a web server by default. Here's how to add a simple API endpoint:

```dart
import 'package:serverpod/serverpod.dart';

class HelloRoute extends Route {
@override
Future<Result> handleCall(Session session, Request request) async {
return Response.ok(
body: Body.fromString(
jsonEncode({'message': 'Hello from Serverpod!'}),
mimeType: MimeType.json,
),
);
}
}
```

Register the route in your `server.dart` file before starting the server:

```dart
pod.webServer.addRoute(HelloRoute(), '/api/hello');
await pod.start();
```

Visit `http://localhost:8080/api/hello` to see your API response.

## Core concepts

### Routes and handlers

A **Route** is a destination in your web server that handles requests and generates responses. Routes extend the `Route` base class and implement the `handleCall()` method:

```dart
class ApiRoute extends Route {
@override
Future<Result> handleCall(Session session, Request request) async {
// Your logic here
return Response.ok();
}
}
```

The `handleCall()` method receives:

- **Session** - Access to your database, logging, and authenticated user
- **Request** - The HTTP request with headers, body, and URL information

### Response types

Return different response types based on your needs:

```dart
// Success responses
return Response.ok(body: Body.fromString('Success'));
return Response.created(body: Body.fromString('Created'));
return Response.noContent();

// Error responses
return Response.badRequest(body: Body.fromString('Invalid input'));
return Response.unauthorized(body: Body.fromString('Not authenticated'));
return Response.notFound(body: Body.fromString('Not found'));
return Response.internalServerError(body: Body.fromString('Server error'));
```

### Adding routes

Routes are added with a path pattern:

```dart
// Exact path
pod.webServer.addRoute(UserRoute(), '/api/users');

// Path with wildcard
pod.webServer.addRoute(StaticRoute.directory(Directory('web')), '/static/**');
```

Routes are matched in the order they were added.

## When to use what

### Rest apis → custom routes

For REST APIs, webhooks, or custom HTTP handlers, use custom `Route` classes:

```dart
class UsersApiRoute extends Route {
UsersApiRoute() : super(methods: {Method.get, Method.post});

@override
Future<Result> handleCall(Session session, Request request) async {
if (request.method == Method.get) {
// List users
} else {
// Create user
}
}
}
```

See [Routing](routing) for details.

### Static files → `StaticRoute`

For serving CSS, JavaScript, images, or other static assets:

```dart
pod.webServer.addRoute(
StaticRoute.directory(Directory('web/static')),
'/static/**',
);
```

See [Static Files](static-files) for cache-busting and optimization.

## Database access

The `Session` parameter gives you full access to your Serverpod database:

```dart
class UserRoute extends Route {
@override
Future<Result> handleCall(Session session, Request request) async {
// Query database
final users = await User.db.find(session);

// Use logging
session.log('Retrieved ${users.length} users');

return Response.ok(
body: Body.fromString(
jsonEncode(users.map((u) => u.toJson()).toList()),
mimeType: MimeType.json,
),
);
}
}
```

## Next steps

- **[Routing](routing)** - Learn about HTTP methods, path parameters, and wildcards
- **[Middleware](middleware)** - Add cross-cutting functionality like error handling and logging
- **[Static Files](static-files)** - Serve static assets with cache-busting
- **[Typed Headers](typed-headers)** - Work with HTTP headers in a type-safe way
Loading