Custom function for HTTP action?
I want to use the same authorization process for all HTTP actions in a project rather than including the auth code in each action. I thought a custom action might work, but after reading the Stack post about custom functions, and also reviewing the code in the
convex-helpers package, HTTP actions don't appear to be supported. Am I reading that correctly?27 Replies
Thanks for posting in <#1088161997662724167>.
Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets.
- Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.)
- Use search.convex.dev to search Docs, Stack, and Discord all at once.
- Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI.
- Avoid tagging staff unless specifically instructed.
Thank you!
That's right, you'd need to do something similar. It's not as messy as custom functions because there's less going on, you can wrap a
httpAction without changing as much.Also once you get deep into this you might want to jump to something like https://hono.dev/
(whcih you can run from an httpAction)
But you can write your own
httpAction function without too many type gymnasticsThanks. I don't see us needing that many HTTP actions for our use case, so I probably won't need to go as far as Hono.
As for how to wrap
httpAction, are there any examples on how to do that?
Or should I just review how it's handled for the other functions in convex-helpers?I think we have cors helper that does this... @Tom Redman ?
Yes we have a CORS wrapper that wraps the HttpAction. It should be a good example ā let me grab that link
@Clever Tagline let me know if this works as an example of wrapping the HttpAction: https://github.com/tomredman/convex-cors/blob/main/convex/helpers/corsHttpRouter.ts
GitHub
convex-cors/convex/helpers/corsHttpRouter.ts at main Ā· tomredman/co...
Contribute to tomredman/convex-cors development by creating an account on GitHub.
This wraps the router, but the pattern should be similar. Can dig in more a little later!
Line 290 has an example of wrapping an action.
@Indy @Tom Redman Thank you! I'll dig through that and let you know if I have any more questions.
I got it working. This was a new experience for me, so maybe there's something I could do better, but here's how I implemented it in case it can be useful for others.
Here's my wrapper function (simplified):
I tested the wrapping behavior like so:
In the
http.ts file, authTest was set as the handler on the desired route.
I tested with both valid and invalid credentials, and it performed as desired. š
Being new to writing wrapper functions, my only question is re: the function design. My original version accepted an object with a originalHandler property (following the example in the code you shared), but then I simplified it to just accept a single argument, as using the object felt like unnecessary complexity for my use case. Is there a benefit to doing it one way vs the other?Looks good! I would probably return the original response directly instead of creating a new one, in case there are other things beisdes status, statusText, headers, and body on it.
Simplified seesm great. The versions in convex-helpers are sometimes more general because we want devs to be able to do anything with them, but I wouldn't make your own verison more general than it needs to be.
Good point. š
@ballingt Resurrecting this thread as I'm being alerted to a type issue, and I don't understand why.
Here's the current state of the wrapper:
I haven't opened the file in a while, and haven't been notified of any errors, so I believe it's still working. However, the
originalHandler is now flagged with a type error (see screenshot)
Any ideas why it would do this? I haven't updated the Convex package in my repo in a while, and I'm still on 1.16.3. Do you know if an update would fix this? I couldn't find anything in the changelog specifically related to this issue.
strange if you haven't updated anything! PublicHttpAction is indeed no longer callable, this was dropped around the same time that calling mutations, queries, and actions directly was disabled. https://github.com/get-convex/convex-js/blob/main/CHANGELOG.md#1180
I'd build as a a function
authCheckHttpAction(inner: (ctx, Request) => Response) today insteadGitHub
convex-js/CHANGELOG.md at main Ā· get-convex/convex-js
TypeScript/JavaScript client library for Convex. Contribute to get-convex/convex-js development by creating an account on GitHub.
Thanks. If PublicHttpAction is no longer callable, then clearly I updated the package at some point, but it's obviously been a while as my version is way behind.
I'll try your suggestion and let you know if I hit any snags.
If you need a quick fix, in the latest package there are two private (you won't have types for them, and they're not stable, but they'll work for now) ways to call an http action: https://github.com/get-convex/convex-js/blob/ff3a40c2116f1a0857c1993b95a347e6f844ed1c/src/server/registration.ts#L437-L440
but in general we don't want these to be callable so that it's not confusing for things like whether middleware or arg or return validators run or not when these are called directly, we want httpAction to be the outermost layer
Gotcha. I don't mind going the route that you first suggested, but I'll admit that I don't completely understand it now that I'm actually trying to update the code. Here's where I'm at so far:
With that done, do I just change everything that uses the old function to use this new one instead? E.g.
Am I understanding that correctly?
Now that I've typed all that out, it doesn't look much different than the original. Clearly something isn't clicking, and I don't know what it is...
I also tried to test the private
invokeHttpAction method after updating to the latest version of Convex, but I'm getting an error that the property doesn't exist.
Not sure where to go from hereAh I don't think you should use httpAction in the inner part
Sorry. I think I misinterpreted your comment above:
I'd build as a a function authCheckHttpAction(inner: (ctx, Request) => Response) today instead
just a sec, I'll write one
Thanks. Sorry for taking your time on this.
@ballingt Hang on. I'm getting an idea. Let me see if I can work this out without taking your time.
haven't tried it but this is what I'm thinking
this also lets you customize the interface if you want
Thanks. That looks promising, and definitely better than my approach. While I understand what this does, this isn't the kind of thing that my mind naturally goes to, and I'm not sure what it'll take to get to that point.
totally, this is in line with the middleware in convex-helpers, it helps to see a pattern; we should put this in docs as an example.
It can also be nice to outsource this all to Hono, which we need an example of too; if you want to live in that ecosystem it can be nice to have a fully-featured router instead of the clear-but-simple convex one
Eh...I'm not sure if I want to live in that ecosystem, frankly. Servers intimidate me. I'm happy to solve problems at the data and application levels, but I prefer to leave deeper stuff like server ops to more skilled folks.
Oh I was thinking using Hono in Convex; same Convex-deals-with-servers-for-me setup, but using a different JavaScript library to do the routing
...I'm not following you.
But that's okay. My head feels awful today, so Iām going to stop while I've got a working thing and move on.