Conversation
|
Would love to see this merged! I was looking at writing one myself, and saw you'd already done it, @fabrv. |
|
@zth could you take a look at this PR? :) |
There was a problem hiding this comment.
Looks good, thank you!
Route object limitation is fine honestly. However. it would be nice to support static responses, since they have such a perf benefit according to Bun.
One way to do that could be to leverage unboxed variants, while making Repsonse.t a private {} instead of abstract. Sample code and playground:
module Server = {
type t
}
module Response = {
// Make this `private {}` instead of abstract, so it can be used in unboxed variants with multiple payloads. Beware, the formatter has a bug where `private` is removed, so you'll need to save without formatting.
type t = private {}
}
module BunRequest = {
type t
@get
external params: t => Dict.t<string> = "params"
@get
external cookies: t => Iterator.t<(string, string)> = "cookies"
}
// Allow setting static or function
@unboxed
type routeHandlerForMethod =
Static(Response.t) | Handler((BunRequest.t, Server.t) => promise<Response.t>)
type routeHandlerObject = {
@as("DELETE") delete?: routeHandlerForMethod,
@as("GET") get?: routeHandlerForMethod,
@as("HEAD") head?: routeHandlerForMethod,
@as("OPTIONS") options?: routeHandlerForMethod,
@as("PATCH") patch?: routeHandlerForMethod,
@as("POST") post?: routeHandlerForMethod,
@as("PUT") put?: routeHandlerForMethod,
}
type routes = Dict.t<routeHandlerObject>
Your example would then be:
let server = Bun.serve({
routes: Dict.fromArray([
("/api/status", Handler(apiStatus))
,("/users/:id", Handler(userId))
,("/api/posts", Handler(posts))
,("/blog/hello", Handler(redirect))
]),
fetch: async (_request, _server) => Response.make("Not found", ~options={status: 404})
})What do you think about that?
|
@zth That's great, I didn't knew that trick! With that change we still need to name every method per route, but at least now we can have a static response for a method. The example would actually look like this: let apiStatus: Bun.routeHandlerObject = {
// here's where the variant is used
get: Handler(async (_request, _server) => Response.make("OK"))
post: Static(Response.make("This is static"))
}
let server = Bun.serve({
routes: Dict.fromArray([
("/api/status", apiStatus)
])
})For it to be a variant at the route level it would need to be something like this: @unboxed
type routeHandler =
| Static(Response.t)
| Methods(routeHandlerObject)
type routes = Dict.t<routeHandler>But obviously that's not possible because both I agree that the Route object limitation is fine and with the btw, I updated the PR and ran |
* note about 2.x * fix: update depracated getWithDefault from Readme (#10) * Add `routes` object in `serveOptions` (#11) * feat: add router to serveOptions * remove empty line * change Promise.t to promise in router handler * add unboxed variant type for static and handler method responses * Basic Sqlite bindings (#12) * changelog * basic bindings for SQLite * changelog * chore: add changesets for release (#15) * add unreleased changes as changesets * try changing config * permissions * feat: bun redis bindings (#14) * feat: bun redis bindings * fix: resolve unit test * fix: resolve playground tests * Version Packages (#16) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * package lock * 2.0.0-alpha.1 and rescript v12 support * up readme * Update to ReScript v12 * Run test * Add changelog entry * Revert shell test change --------- Co-authored-by: Gabriel Nordeborn <gabbe.nord@gmail.com> Co-authored-by: Fabrizio Delcompare <35388973+fabrv@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Hi again!
These are some basic bindings for Bun's built-in routing (Bun >1.2.3).
It has a very big limitation that you'd always have to define the methods for each route handler, so there is no easy way to make a wildcard fallback, but for starters it's pretty good.
Here's the code example from https://bun.sh/docs/api/http with the new bindings: