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

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

Closed
cmawhorter opened this issue Sep 19, 2024 · 2 comments
Closed

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

cmawhorter opened this issue Sep 19, 2024 · 2 comments
Labels
add new content Document something that is not in docs. May require testing, confirmation, or affect other pages.

Comments

@cmawhorter
Copy link

📚 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:

  • Provide some context on how this call to the endpoint is made: Is it literally just calling the endpoint function, and does that mean APIContext is the same Astro global I pass i.e. url/etc. will be incorrect? Or is there some magic happening?
  • Mention that dynamic routes are either not supported, or provide a recommendation for how params should be passed

🖥️ 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 cmawhorter added the add new content Document something that is not in docs. May require testing, confirmation, or affect other pages. label Sep 19, 2024
@cmawhorter
Copy link
Author

cmawhorter commented Sep 19, 2024

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.

@TheOtterlord
Copy link
Member

Yeah, this is definitely the better approach. I think we'll discuss retiring this article and recommending people just separate out their logic. Do let me know if you have any use-case where this pattern makes more sense though!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
add new content Document something that is not in docs. May require testing, confirmation, or affect other pages.
Projects
None yet
Development

No branches or pull requests

2 participants