Change event pattern for custom HTTP endpoints

pull/989/head
Zef Hemel 2024-07-27 09:26:55 +02:00
parent b6848f4bbb
commit c80976d10e
2 changed files with 19 additions and 13 deletions

View File

@ -221,10 +221,11 @@ export class HttpServer {
}
try {
const path = url.pathname.slice(2); // Remove the /_
const responses: EndpointResponse[] = await spaceServer.serverSystem
.eventHook.dispatchEvent("http:request", {
.eventHook.dispatchEvent(`http:request:${path}`, {
fullPath: url.pathname,
path: url.pathname.slice(2),
path,
method: req.method,
body: await req.text(),
query: Object.fromEntries(
@ -233,9 +234,15 @@ export class HttpServer {
headers: req.header(),
} as EndpointRequest);
if (responses.length === 0) {
return ctx.text("No response from event hook", 500);
return ctx.text(
"No custom endpoint handler is handling this path",
404,
);
} else if (responses.length > 1) {
return ctx.text("Multiple responses from event hook", 500);
return ctx.text(
"Multiple endpoint handlers are handling this path, this is not supported",
500,
);
}
const response = responses[0];
if (response.headers) {

View File

@ -136,12 +136,12 @@ silverbullet.registerEventListener({name: "task:stateChange"}, async (event) =>
## Custom HTTP endpoints
Using the `registerEventListener` mechanism it is possible to expose custom HTTP endpoint on your SilverBullets server under the `/_/` prefix.
Whenever a HTTP request is sent to your SilverBullet server under this prefix, for instance `https://notes.myserver.com/_/hello` a `http:request` event is emitted. If a handler responds to it, this response will be used as the HTTP response.
Whenever a HTTP request is sent to your SilverBullet server under this prefix, for instance `https://notes.myserver.com/_/hello` a `http:request:/hello` event is emitted. If a handler responds to it, this response will be used as the HTTP response.
> **warning** Warning
> Custom HTTP endpoints are not authenticated. If you want to add authentication, you have to do this manually, e.g. by checking for an “Authorization” header in your code.
For the `http:request` the `data` key takes the shape of a EndpointRequest object, which in TypeScript is defined as follows:
For `http:request:*` events, the `data` key takes the shape of a EndpointRequest object, which in TypeScript is defined as follows:
```typescript
type EndpointRequest = {
@ -175,19 +175,18 @@ type EndpointResponse = {
### Example
```space-script
silverbullet.registerEventListener({name: "http:request"}, (event) => {
silverbullet.registerEventListener({name: "http:request:/echo"}, (event) => {
const req = event.data;
if(req.path === "/echo") {
// Simply echo back the request
return {
body: JSON.stringify(req, null, 2)
};
}
});
```
You can try it out here: https://silverbullet.md/_/echo
**Note:** Since event names support wildcards, you can write event listeners to prefixes as well, e.g. `http:request:/something/*`.
# Custom attribute extractors
SilverBullet indexes various types of content as [[Objects]]. There are various ways to define [[Attributes]] for these objects, such as the [attribute: my value] syntax. However, using space script you can write your own code to extract attribute values not natively supported using the registerAttributeExtractor API.