Skip to content

Commit

Permalink
Document catch all routes (#214)
Browse files Browse the repository at this point in the history
* feat: document catch-all routes

---------

Co-authored-by: Ángel M <[email protected]>
  • Loading branch information
ereslibre and Angelmmiguel authored Sep 13, 2023
1 parent 85309ee commit 65c71c7
Show file tree
Hide file tree
Showing 11 changed files with 302 additions and 55 deletions.
16 changes: 8 additions & 8 deletions docs/docs/features/all.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ You can develop workers in different languages. However, not all of them support

The following table shows the language compatibility for the different worker functions:

| Language | K/V Store | Environment Variables | Dynamic Routes | Folders | HTTP Requests |
| --- | --- | --- | --- | --- | --- |
| JavaScript ||||||
| Rust ||||||
| Go ||||||
| Ruby ||||||
| Python ||||||
| Zig ||||||
| Language | K/V Store | Environment Variables | Dynamic Routes | Folders | HTTP Requests |
|------------|-----------|-----------------------|----------------|---------|---------------|
| JavaScript | | | | | |
| Rust | | | | | |
| Go | | | | | |
| Ruby | | | | | |
| Python | | | | | |
| Zig | | | | | |
66 changes: 58 additions & 8 deletions docs/docs/features/dynamic-routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,63 @@ $ tree .

In this case, the `./[resource]/[id]/show.js` worker replies to URLs like `/articles/2/show`.

## Catch-all routes

Catch-all routes are route segments that can be matched with any path segment on the route. For example, you can use catch-all routes by having a directory structure like the following:

```
$ tree .
.
└── [...slug]
└── index.js
```

This means, that the JavaScript worker at `[...slug]/index.js` will serve any path beneath. You can mix and match specific routes with catch-all routes. For example, given the following directory structure:

```
$ tree .
.
├── about.js
└── [...slug]
└── index.js
```

In this example, two workers are fulfilling HTTP requests:

- `/about` is served by the `about.js` worker.
- Anything else under `/` is served by the `[...slug]/index.js` worker.

You can also place multiple catch-all routes as long as they are splitted by a non-catch-all segment. For example:

```
$ tree .
.
├── about.js
├── other
│   └── [...slug]
│   └── index.js
└── [...slug]
└── index.js
```

Here, we have the same structure as in the previous example, but we have two catch-all, under two different roots:

- One catch-all, `[...slug]/index.js` is serving all requests, except for requests whose path starts with `/about` or `/other`.
- Another catch-all, `other/[...slug]/index.js` serves all requests under the `/other` path.

**You can also define segments at at the trailing of the URL**, by having a worker in the filesystem of the form `/some/resource/[...slug].js`. This worker will serve requests at the path `/some/resource/<slug>`.

### Routing priority

Given catch-all routes could potentially shadow other routes, it is important to settle precedence when routing requests. **The rule of thumb is more specific routes win**. For example, a route with no catch-all will always against a route with catch-all when they are at the same depth.

## Language compatibility

| Language | Dynamic routes |
| --- | --- |
| JavaScript ||
| Rust ||
| Go ||
| Ruby ||
| Python ||
| Zig ||
| Language | Dynamic routes |
|------------|----------------|
| JavaScript | |
| Rust | |
| Go | |
| Ruby | |
| Python | |
| Zig | |
16 changes: 8 additions & 8 deletions docs/docs/features/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ This feature allows you to configure environment variables dynamically.

## Language compatibility

| Language | Environment variables |
| --- | --- |
| JavaScript ||
| Rust ||
| Go ||
| Ruby ||
| Python ||
| Zig ||
| Language | Environment variables |
|------------|-----------------------|
| JavaScript | |
| Rust | |
| Go | |
| Ruby | |
| Python | |
| Zig | |
16 changes: 8 additions & 8 deletions docs/docs/features/http-requests.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ Check these guides to perform HTTP requests in the different supported languages

## Language compatibility

| Language | HTTP Requests |
| --- | --- |
| JavaScript ||
| Rust ||
| Go ||
| Ruby ||
| Python ||
| Zig ||
| Language | HTTP Requests |
|------------|---------------|
| JavaScript | |
| Rust | |
| Go | |
| Ruby | |
| Python | |
| Zig | |
16 changes: 8 additions & 8 deletions docs/docs/features/key-value.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ A known limitation of the snapshot approach is the data override when concurrent

## Language compatibility

| Language | K/V store |
| --- | --- |
| JavaScript ||
| Rust ||
| Go ||
| Ruby ||
| Python ||
| Zig ||
| Language | K/V store |
|------------|-----------|
| JavaScript | |
| Rust | |
| Go | |
| Ruby | |
| Python | |
| Zig | |
14 changes: 7 additions & 7 deletions docs/docs/features/machine-learning.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ We recommend to check this example to get started with ML and Wasm Workers Serve

## Language compatibility

| Language | Machine learning inference |
| --- | --- |
| JavaScript ||
| Rust ||
| Go ||
| Ruby ||
| Python ||
| Language | Machine learning inference |
|------------|----------------------------|
| JavaScript | |
| Rust | |
| Go | |
| Ruby | |
| Python | |
16 changes: 8 additions & 8 deletions docs/docs/features/mount-folders.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ Note that those folders may include files that `wws` recognizes as workers (like

## Language compatibility

| Language | Mount folders |
| --- | --- |
| JavaScript ||
| Rust ||
| Go ||
| Ruby ||
| Python ||
| Zig ||
| Language | Mount folders |
|------------|---------------|
| JavaScript | |
| Rust | |
| Go | |
| Ruby | |
| Python | |
| Zig | |
23 changes: 23 additions & 0 deletions examples/js-catchall/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# JavaScript catch-all example

This worker showcases how catch-all routes can be used by your workers.


## Prerequisites

* Wasm Workers Server (wws):

```shell-session
curl -fsSL https://workers.wasmlabs.dev/install | bash
```

## Run

```shell-session
wws https://github.com/vmware-labs/wasm-workers-server.git -i --git-folder "examples/js-catchall"
```

## Resources

* [Catch-all routes](https://workers.wasmlabs.dev/docs/features/catch-all-routes)
* [JavaScript documentation](https://workers.wasmlabs.dev/docs/languages/javascript)
58 changes: 58 additions & 0 deletions examples/js-catchall/[...slug]/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Builds a reply to the given request
*/
const reply = (request) => {
if (request.method != "GET") {
// Don't allow other methods.
// Here you can see how to return a custom status
return new Response("Method not allowed", {
status: 405
});
}

// Body response
const body = `<!DOCTYPE html>
<head>
<title>Wasm Workers Server</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
<style>
body { max-width: 1000px; }
main { margin: 5rem 0; }
h1, p { text-align: center; }
h1 { margin-bottom: 2rem; }
pre { font-size: .9rem; }
pre > code { padding: 2rem; }
p { margin-top: 2rem; }
</style>
</head>
<body>
<main>
<h1>Hello from Wasm Workers Server 👋</h1>
<pre><code>Replying to ${request.url}
Method: ${request.method}
User Agent: ${request.headers.get("user-agent")}
Payload: ${request.body || "-"}</code></pre>
<p>
<b>This worker is replying to the top-level catch-all endpoint.</b>
</p>
<p>
This page was generated by a JavaScript file running in WebAssembly.
</p>
</main>
</body>`;

// Build a new response
let response = new Response(body);

// Add a new header
response.headers.set("x-generated-by", "wasm-workers-server");

return response;
}

// Subscribe to the Fetch event
addEventListener("fetch", event => {
return event.respondWith(reply(event.request));
});
58 changes: 58 additions & 0 deletions examples/js-catchall/about.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Builds a reply to the given request
*/
const reply = (request) => {
if (request.method != "GET") {
// Don't allow other methods.
// Here you can see how to return a custom status
return new Response("Method not allowed", {
status: 405
});
}

// Body response
const body = `<!DOCTYPE html>
<head>
<title>Wasm Workers Server</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
<style>
body { max-width: 1000px; }
main { margin: 5rem 0; }
h1, p { text-align: center; }
h1 { margin-bottom: 2rem; }
pre { font-size: .9rem; }
pre > code { padding: 2rem; }
p { margin-top: 2rem; }
</style>
</head>
<body>
<main>
<h1>Hello from Wasm Workers Server 👋</h1>
<pre><code>Replying to ${request.url}
Method: ${request.method}
User Agent: ${request.headers.get("user-agent")}
Payload: ${request.body || "-"}</code></pre>
<p>
<b>This worker is replying to the <code>/about</code> endpoint.</b>
</p>
<p>
This page was generated by a JavaScript file running in WebAssembly.
</p>
</main>
</body>`;

// Build a new response
let response = new Response(body);

// Add a new header
response.headers.set("x-generated-by", "wasm-workers-server");

return response;
}

// Subscribe to the Fetch event
addEventListener("fetch", event => {
return event.respondWith(reply(event.request));
});
58 changes: 58 additions & 0 deletions examples/js-catchall/other/[...slug].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Builds a reply to the given request
*/
const reply = (request) => {
if (request.method != "GET") {
// Don't allow other methods.
// Here you can see how to return a custom status
return new Response("Method not allowed", {
status: 405
});
}

// Body response
const body = `<!DOCTYPE html>
<head>
<title>Wasm Workers Server</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
<style>
body { max-width: 1000px; }
main { margin: 5rem 0; }
h1, p { text-align: center; }
h1 { margin-bottom: 2rem; }
pre { font-size: .9rem; }
pre > code { padding: 2rem; }
p { margin-top: 2rem; }
</style>
</head>
<body>
<main>
<h1>Hello from Wasm Workers Server 👋</h1>
<pre><code>Replying to ${request.url}
Method: ${request.method}
User Agent: ${request.headers.get("user-agent")}
Payload: ${request.body || "-"}</code></pre>
<p>
<b>This worker is replying to the catch-all endpoint under <code>/other</code>.</b>
</p>
<p>
This page was generated by a JavaScript file running in WebAssembly.
</p>
</main>
</body>`;

// Build a new response
let response = new Response(body);

// Add a new header
response.headers.set("x-generated-by", "wasm-workers-server");

return response;
}

// Subscribe to the Fetch event
addEventListener("fetch", event => {
return event.respondWith(reply(event.request));
});

0 comments on commit 65c71c7

Please sign in to comment.