Quick Start
The guide will leave you with both a decent understanding of webroute and a starting point to build a real-world app. The resulting app will have the following:
- End-to-end type-safety
- Automatic OpenAPI spec generation
- Input/output validation
- Authentication middleware
- Compatibility with many runtimes and frameworks
To get started immediately, you can bootstrap a standalone webroute app via:
Creating API routes
1. Define a Route
To begin, we'll create a single POST
route for creating new blog posts.
This basic route, createPostRoute
, is a web-standard request handler which can be run nearly anywhere, including Next.js
API routes, within a Hono
app or as part of a standalone Bun
or Node
app.
But our route isn't doing anything interesting yet!
2. Add Input Validation
Validating the inputs and outputs coming in and out of our server is a critical component of any serious backend application. Webroute's offer first-class support for specifying validation schema, supporting all popular schema libraries.
By specifying our schema up front, our routes more declarative and enable OpenAPI spec generation, type-inference and end-to-end type-safety, among other things.
We can also specify schema for path .params()
, .query()
params, .headers()
and response .output()
s.
Bear in mind, inputs are only parsed upon calling the .parse()
method, to
enable greater flexibility with error handling.
Using Middleware
Middleware is a common part of any web framework. In webroute, return values are used to update request state, return early with a response or listen to and modify outgoing responses.
1. Define Auth Middleware
We want to ensure only logged in users can create posts. Since we expect this to be a fairly common use case, we can use middleware and composition to avoid unnecessary repititon.
Our middleware simply returns any state updates and requires no bespoke API calls like next()
, nor can we modify the immutable request
object.
Learn more about what can be achieved by different middleware return types.
Note that defineMiddleware
is not doing anything special under the hood. It
is used to ensure your middleware has compatible parameter and return types.
2. Register Middleware on Routes
To register this with a route, we can call the .use()
method. We can also – optionally – use composition to create a reusable base route for any future authed routes.
The .state
property of our requet context, c
, houses all the data returned from any middleware on the way to our request handler. Because webroutes are immutable, we can reuse our base routes and maintain independent state between them. By using this pattern, our middleware is automatically type-safe with no extra work.
Routing
Most of the time, we have multiple routes that we want to map an incoming request to. In other words, we require routing of some sort.
Filesystem Routing
In filesystem routing contexts like Next.js, we can just export our routes as-is from route handler files (or their equivalent).
Learn more about integrating with full-stack frameworks.
Manual Routing
For explicit routing, we can use a router from the @webroute/router
package to help us map requests to the various route handlers we have.
First, we should collect all of our routes into a single object.
This router allows us to match handler based on an incoming request. Therefore, our router can also be used anywhere web-standard requests are supported.
This root request handler is, in essence, our "app". It is the entrypoint of our API. Exactly how we use this entrypoint depends on the framework or runtime we decide to use.
Next Steps
To understand how to run your webroute app, check out one of the many integration guides.
Full-stack Frameworks
Standalone
Web Frameworks
More Functionality
Webroute also provides additional packages for further enhancing or interacting with APIs.
- Use
@webroute/client
to create typed API clients for any API - Use
@webroute/oas
to define and create OpenAPI specs