withastro / docs

Astro documentation
https://docs.astro.build/
MIT License
1.3k stars 1.45k forks source link

Expand and clarify "Call endpoints from the server" recipe page #9448

Open cmawhorter opened 2 days ago

cmawhorter commented 2 days ago

📚 Subject area/topic

Calling server endpoints on the server

📋 Suggested page

This page exists here, but is lacking: https://docs.astro.build/en/recipes/call-endpoints/

This was kinda previously brought up in #4767 and the docs page is a good start, but the example provided is very basic and I feel that more context/details are needed.

📋 General description or bullet points (if proposing new content)

Suggestions:

🖥️ Reproduction of code samples in StackBlitz

When it comes to passing params when calling an endpoint on the server, #4767 commenters offered two possibilities, and neither feel great.

spread:

import { GET } from './api/[id].ts'
let response = await GET({
  ...Astro,
  params: { id: '1' },
});

use astro middleware util createContext, which appears undocumented from a quick search of astro docs:

import { createContext } from "astro/middleware";
import { GET } from './api/[id].ts'

const context = createContext({
  request: Astro.request,
  params: { id: '1' },
});

in both cases, the details of the request passed to the api server endpoint are for the current page and not the api endpoint being called. at least, that's my assumption as i didn't confirm.

at any rate, some clarification on this recipe would be much appreciated.

cmawhorter commented 2 days ago

Oof. I was definitely over-thinking this...

This would probably be a better solution:

import type { APIRoute } from 'astro'

interface IGetRouteRequirements {
  id: string;
  locals: {...};
  ...
}

const handleGetRoute = (data: IGetRouteRequirements) => {
  return {
    greeting: `Hello ${data.locals.session.name} with ID ${data.id}`,
  };
};

export const GET: APIRoute = (context) => {
  const data = handleGetRoute({id: context.params.id, locals: context.locals});
  return new Response(
    JSON.stringify(data),
  )
}
---
import { handleGetRoute } from './api/[id].ts'

const data = handleGetRoute({id: '1', locals: Astro.locals});
---

<h1>{data.greeting} world!</h1>

Feel free to close.