diff --git a/server/http_server.ts b/server/http_server.ts index 8c9f55d3..69afb758 100644 --- a/server/http_server.ts +++ b/server/http_server.ts @@ -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) { diff --git a/website/Space Script.md b/website/Space Script.md index efa5fa14..ffe79955 100644 --- a/website/Space Script.md +++ b/website/Space Script.md @@ -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 SilverBullet’s 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) - }; - } + // 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.