Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document catch all routes #214

Merged
merged 4 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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.
ereslibre marked this conversation as resolved.
Show resolved Hide resolved

**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));
});