Typed API - Allow calling from the server
Hi there, I was testing the astro-typed-api library and it works great. The only issue I found was that I wanted to reuse an endpoint from an astro action but I get:
The API request to http://localhost:4321/api/organizations/9zKZPo6CyDCotV22JNF9CCBHoVg2cFVH/members/me/role was made by an unsupported client.
The request's Accept header must include either application/json or application/escodec.
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" included neither.
See error.cause for the full request.
I can get a response if I send only the Accept header but if I add any other header it throw the error. This is how I'm making the API call from the action:
const member = await fetch(
`http://localhost:4321/api/organizations/${organizationId}/members/me/role`,
{
headers: {
"accept": "application/json",
"cookie": ctx.request.headers.get("cookie") ?? "",
},
},
).then((res) => res.json());
PS: A server client would be nice :)
I wanted to reuse an endpoint from an astro action
For my clarification, you need another part of the server code, src/actions/*.ts specifically, to reuse the logic written inside a typed API route. Is that right?
PS: A server client would be nice :)
So true! Currently you can import from the API route module and call GET.fetch()/ POST.fetch manually, but that requires an if-else statement if the same code needs to run in the browser as well.
As a new feature, it is possible for the api object to check that it is running on the server and skip making an HTTP request altogether.
For my clarification, you need another part of the server code, src/actions/*.ts specifically, to reuse the logic written inside a typed API route. Is that right?
Yes, exactly! Astro pages could also benefit from this. I know that you can probably write the logic there but sometimes code is reused across client and server and caching specific requests like we can do in endpoints its really useful.
As a new feature, it is possible for the api object to check that it is running on the server and skip making an HTTP request altogether.
Yes, and also It would be super clear — although the astro-typed-api/client is more than clear — if it throws a "client api is not available in the server and it's only available for client usage".
Implemented basic support in v0.5.0. Although it is basic, it should be enough for at least 80% of the use cases.
Keeping this open for feedback.
Nice, that was fast! I'm wondering why a manual call doesn't work and throws an error like I sent you before 🤔
const member = await fetch(
`http://localhost:4321/api/organizations/${organizationId}/members/me/role`,
{
headers: {
"accept": "application/json",
"cookie": ctx.request.headers.get("cookie") ?? "",
},
},
).then((res) => res.json());
This call is problematic because the server is calling itself. It could get stuck in a loop if you're not careful. But it should work, what was the error?
True, it was my mistake. Thanks :)