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

feat(server): added express adapter #71

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

unteifu
Copy link
Contributor

@unteifu unteifu commented Jan 3, 2025

I've added an express adapter that achieves the following:

  • Let's express handle 404 errors as designed
  • Simplifies instantiating the handler into 1 simple function while still allowing for all options to be passed

This is a big step forward for using oRPC in express as it provides a clean dev syntax while bringing the logic more behind the adapter and ensuring it follows express' standards. No performance hits should be made as it is just a simple abstraction layer.

Copy link

vercel bot commented Jan 3, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
orpc ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 4, 2025 4:28pm

Copy link

pkg-pr-new bot commented Jan 3, 2025

Open in Stackblitz

More templates

@orpc/client

npm i https://pkg.pr.new/@orpc/client@71

@orpc/contract

npm i https://pkg.pr.new/@orpc/contract@71

@orpc/openapi

npm i https://pkg.pr.new/@orpc/openapi@71

@orpc/next

npm i https://pkg.pr.new/@orpc/next@71

@orpc/react

npm i https://pkg.pr.new/@orpc/react@71

@orpc/react-query

npm i https://pkg.pr.new/@orpc/react-query@71

@orpc/server

npm i https://pkg.pr.new/@orpc/server@71

@orpc/shared

npm i https://pkg.pr.new/@orpc/shared@71

@orpc/vue-colada

npm i https://pkg.pr.new/@orpc/vue-colada@71

@orpc/vue-query

npm i https://pkg.pr.new/@orpc/vue-query@71

@orpc/zod

npm i https://pkg.pr.new/@orpc/zod@71

commit: d668f25

@unnoq
Copy link
Owner

unnoq commented Jan 4, 2025

Hey @unteifu, I understand why you need this—it might help when mixing routes between Express.js and oRPC.

Unfortunately, there's currently no way to distinguish between a 404 caused by a route mismatch and one originating from the handler itself. I’m considering adding an option like ignoreWhenMismatchError to address this. With that, you could implement your logic bellow handle function if needed or even Official adapter for Express.js and Hono.js

@unteifu
Copy link
Contributor Author

unteifu commented Jan 4, 2025

Hey @unteifu, I understand why you need this—it might help when mixing routes between Express.js and oRPC.

Unfortunately, there's currently no way to distinguish between a 404 caused by a route mismatch and one originating from the handler itself. I’m considering adding an option like ignoreWhenMismatchError to address this. With that, you could implement your logic bellow handle function if needed or even Official adapter for Express.js and Hono.js

This will handle what you describe as it goes through all routes in the handler then will mark the status as 404 as good practice if none match but any other routes below oRPC's managed ones can still change that if it matches, it'll pass down then to the next handlers in the chain as the route isnt available in oRPC. You shouldn't need to know where the 404 originates from because oRPC is contract first/strict you know it'll originate from an invalid endpoint that's not defined in the contract and at that point it's not oRPC's responsibility to know it's origin as then it's in the scope of express to determine it as it could be from an endpoint which oRPC doesnt manage.

@unnoq
Copy link
Owner

unnoq commented Jan 4, 2025

You shouldn't need to know where the 404 originates

Someone on Discord recently reminded me about the distinction between a 404 returned by a handler and a 404 from a route mismatch.

A 404 from a handler is typically used to indicate that a specific resource, like an ID, wasn't found in the database. It's important to respect this error and respond immediately to the user, as it's conveying meaningful information about the resource's unavailability.

@unteifu
Copy link
Contributor Author

unteifu commented Jan 4, 2025

You shouldn't need to know where the 404 originates

Someone on Discord recently reminded me about the distinction between a 404 returned by a handler and a 404 from a route mismatch.

A 404 from a handler is typically used to indicate that a specific resource, like an ID, wasn't found in the database. It's important to respect this error and respond immediately to the user, as it's conveying meaningful information about the resource's unavailability.

404's thrown in the handler for like a user not found etc still work as intended/respected as I agree we should be respecting and won't fall to the global one defined below the middleware like in the example I made changes to. So you could theoretically still include extra meta into handler based 404's if desired etc without any changes.

@unnoq
Copy link
Owner

unnoq commented Jan 4, 2025

You shouldn't need to know where the 404 originates

Someone on Discord recently reminded me about the distinction between a 404 returned by a handler and a 404 from a route mismatch.
A 404 from a handler is typically used to indicate that a specific resource, like an ID, wasn't found in the database. It's important to respect this error and respond immediately to the user, as it's conveying meaningful information about the resource's unavailability.

404's thrown in the handler for like a user not found etc still work as intended/respected as I agree we should be respecting and won't fall to the global one defined below the middleware like in the example I made changes to. So you could theoretically still include extra meta into handler based 404's if desired etc without any changes.

It can, but only one special error like this 404-mismatch, so I think we could make it more simple

@unteifu
Copy link
Contributor Author

unteifu commented Jan 4, 2025

You shouldn't need to know where the 404 originates

Someone on Discord recently reminded me about the distinction between a 404 returned by a handler and a 404 from a route mismatch.
A 404 from a handler is typically used to indicate that a specific resource, like an ID, wasn't found in the database. It's important to respect this error and respond immediately to the user, as it's conveying meaningful information about the resource's unavailability.

404's thrown in the handler for like a user not found etc still work as intended/respected as I agree we should be respecting and won't fall to the global one defined below the middleware like in the example I made changes to. So you could theoretically still include extra meta into handler based 404's if desired etc without any changes.

It can, but only one special error like this 404-mismatch, so I think we could make it more simple

I think that's out of the scope of the adapter I've made as it's looking to be more a simpler container for the logic so it complies with express' conventions and standards as currently it doesn't. I think if we want to start adding fancy things to it we certainly can look into it but at the core this just adapts oRPC to comply with what express expects to happen.

Might be worth us giving input from others on the matter?

@unnoq
Copy link
Owner

unnoq commented Jan 4, 2025

@unteifu, yes I hope I can release this in today or tomorrow.

Here is draft

const handled: boolean = handler.handle(req,res, {
 ignoreMismatchError: true,
})

if(handled === false){
 next()
} 

Maybe I will release both expressjs and honojs adapter, or let you do that with new option can make it more easy

@unteifu
Copy link
Contributor Author

unteifu commented Jan 4, 2025

@unnoq that looks fine also, if you want to take what i've already done and build on top to handle in that approach that's fine with me as i've already got the type passing sorted for it, by default in these adapters it should ignore mismatches but then we can have an option in the abstracted middleware to toggle it back on perhaps?

I haven't played around with hono in this way but if we're agreeing on this approach/proposal for handling then I can add a playground with hono also and replicate what we do for express to work ok for them also ^^

@unteifu
Copy link
Contributor Author

unteifu commented Jan 4, 2025

I will just note that my changes to the CompositeHandler in this commit actually improved response times by ~5% at 1000 iterations of the handler being called 😄

old:

{
    "totalRequests": 1000,
    "p95ResponseTime": "1.23",
}

new:

{
    "totalRequests": 1000,
    "p95ResponseTime": "1.16",
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants