Merge routes for API requests

default discord avatar
zochhlast year
52

On the home page I am currently using 5 fetch for getting data from 5 collections, and this slows down the page load time. Is there any way to merge the routes so that I can get all the docs under one route?


Current way I'm doing:


const [featured, post, version, category, resolution] =
            await Promise.all([
                fetch(`${SERVER_URL}/api/featured`).then((res) => res.json()),
                fetch(
                    `${SERVER_URL}/api/post?limit=6&${edRe}${catRe}${resRe}${verRe}&sort=${
                        sort ? sort : "-updatedAt"
                    }&page=${currPage ? currPage : 1}`
                ).then((res) => res.json()),
                fetch(`${SERVER_URL}/api/versions?sort=-Versions`).then((res) =>
                    res.json()
                ),
                fetch(`${SERVER_URL}/api/categories?sort=title`).then((res) =>
                    res.json()
                ),
                fetch(`${SERVER_URL}/api/resolutions`).then((res) =>
                    res.json()
                ),
            ]);
  • default discord avatar
    notchrlast year

    @zochh How about a custom endpoint that grabs the data on the backend?



    You can create a custom API route that have access to these collections and can send all the data you need at once



    First you would create the endpoint, for example....

  • default discord avatar
    zochhlast year

    In the

    server.ts

    file? So like a app.get("/route")?

  • default discord avatar
    notchrlast year

    In your payload config file, not server.ts :



        {
          path: "/example",
          method: "get",
          handler: async (req, res, next) => {
            try {
              const exampleA = await req.payload.findByID({
                collection: "exampleA",
                id: req.params.id,
              });
    
              const exampleB = await payload.find({
                collection: "posts",
                depth: 2,
                page: 1,
                limit: 10,
              });
    
              const data = {
                exampleA,
                exampleB
              }
    
              res.status(200).json(data)
              
            } catch (error) {
              console.log(error);
              res.status(500).json("An error message");
            }
          },
        },


    that would go in the "endpoints" array on your main payload ocnfig object



    Endpoints added to the array on your main config are global custom endpoints



    Endpoints added onto collection configs are specific and relative to that collection



    In the endpoint handler function, you can see we have access to req.payload which is the local API



    Does this make sense?



    For all config options in payload, see:

    https://payloadcms.com/docs/configuration/overview
  • default discord avatar
    zochhlast year

    Yep, except the last bit- This can be accessed using the REST API too right? If I make a request to that path

  • default discord avatar
    notchrlast year

    Adding an endpoint means you're adding a new REST API entry



    So that you can send a get/post etc, to

    example.com/my-payload-api/custom-url


    Notice I set the request type to "get"



    you could set it to post and then check data on

    req.body


    It's like adding an express route



    Does that make sense?



    Personally, I would start by adding the most basic endpoint you could



    and try pinging it as a test

  • default discord avatar
    zochhlast year

    Yep, makes sense and got it working

  • default discord avatar
    notchrlast year

    and then once you confirm it's active, expand on that



    YAS



    Nicely done!



    dances


    Let us know if you need any more help, good luck

  • default discord avatar
    zochhlast year

    Thank you so much! Was really annoying to send 5 requests to different collections haha

  • default discord avatar
    notchrlast year

    I'm sure, though in the future if you need to make many requests at a time



    Fetch returns a promise, you're using a lot of .then chains



    If you have an array of promises, you can wait until they are resolved and get the combined data object via

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all


    const array = [promiseA, promiseB, promiseC, promiseD)



    await Promise.all(array)



    etc



    i forget if it is awaited, i think so



    anywho, just a side note 🙂

  • default discord avatar
    zochhlast year

    Oh, I see, gimme a sec



    yep it is

  • default discord avatar
    notchrlast year

    Ah right



    😄

  • default discord avatar
    zochhlast year
     const [post, { featured, version, category, resolution }] =
                await Promise.all([
                    fetch(
                        `${SERVER_URL}/api/post?limit=6&${edRe}${catRe}${resRe}${verRe}&sort=${
                            sort ? sort : "-updatedAt"
                        }&page=${currPage ? currPage : 1}`
                    ).then((res) => res.json()),
                    fetch(`${SERVER_URL}/api/home`).then((res) => res.json()),
                ]);

    so that would be it.

  • default discord avatar
    notchrlast year

    Yeah, though youll have better results with the custom endpoint



    Since the work is being done in one go on the server



    Just wanted to make a note about situations where you cant do that



    and want to await a bunch of promises



    unrelated to your initial question

  • default discord avatar
    zochhlast year

    Would passing the request in the body (then fetching the data using payload.find()) or through URL queries be faster?

  • default discord avatar
    notchrlast year

    Not in this case because it's essentially doing that in the background



    The only reason this situation is better handlded via a custom endpoint (i think), is the overhead of multiple requests to different endpoints



    And even then, it's probably not a noticeable difference



    I could be wrong though, request architecture isn't my strongest suit

  • default discord avatar
    zochhlast year

    Ah its oke, but tysm againtho! This was helpful!

  • default discord avatar
    notchrlast year

    Anytime!!!

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.