Как избежать избыточных вызовов API в SvelteKit при получении данных публикации

Я работаю над приложением SvelteKit, в котором мне нужно получить список данных сообщений и избежать избыточных вызовов API.

  1. Маршрут: all-posts/+page.svelte

    • Получает список сообщений с помощью fetchAllPostsData()
  2. Маршрут: post/[id]/[title]/+page.svelte

    • Снова извлекает данные публикации, используя fetchPostDataById(id)
    • Отображает полученные данные в DOM

Текущая реализация приводит к вызову fetchAllPostsData(), а затем повторному вызову fetchPostDataById(id), что неэффективно. Вот соответствующий код:

all-posts/+page.svelte:

<script>
    import { onMount } from 'svelte';
    import { fetchAllPostsData } from './fetch-post-data';

    let postsDataArr = [];

    onMount(async () => {
        postsDataArr = await fetchAllPostsData();
    });
</script>

<section>
    <ul>
        {#each postsDataArr as post}
            <li><a href = {`/post/${post.id}/${post.title.replace(/[\s ]/g, '-')}`}>{post.title}</a></li>
        {/each}
    </ul>
</section>

post/[id]/[title]/+page.svelte:

<script>
    import { onMount } from 'svelte';
    import { page } from '$app/stores';
  import { fetchPostDataById } from '../fetch-post-data';


    let id;
    /**
     * @type {any}
     */
    let data;

    $: id = $page.params.id;

    onMount(async () => {
        data = await fetchPostDataById(id);
    });
</script>

<section>
    {#if data}
    <div>
        <div>{@html data.html}</div>
    </div>
    {/if}
</section>

Дополнительный контекст:

Я не хочу полностью удалять функцию fetchPostDataById(id), так как это важно в тех случаях, когда пользователи делятся прямой ссылкой на публикацию. В таких сценариях ссылка на публикацию должна получать данные публикации по идентификатору, чтобы гарантировать отображение правильных данных, даже если пользователь обращается к публикации напрямую через URL-адрес.

Вопрос:

Как я могу реорганизовать свой код, чтобы избежать повторного вызова API? Я хочу получить список сообщений один раз и использовать эти данные в обоих маршрутах без избыточной выборки.


Обновление после получения ответа и предложения

Теперь я использую TanStack Query в Svelte вместо того, чтобы каждый раз напрямую вызывать API. Подробнее читайте в официальном документе

<script lang = "ts">
  import { createQuery } from '@tanstack/svelte-query';

  // Define the options for the fetch request
  const options = {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({"limit":100})
  };

  // Fetch function to get paginated posts
  const fetchPaginatedPosts = async () => {
    try {
      const response = await fetch('http://localhost:4000/get-paginated-posts', options);
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
        const res = await response.json()
        console.info(res)

          /*
            res = {
              "posts": [
                  {
                      "id": "667776bcc5d22d6226f7647b",
                      "description": "Hello, this is me!",
                      "title": "My page is here!",
                      "update_count": 0,
                      "updated_at": "2024-06-23T10:13:32.190+00:00"
                      "created_at": "2024-06-23T10:13:32.190+00:00",
                      "created_by": "666ff11d406248baf2e87df4",
                  } ,{...}
              ],
              "nextToken": "667776bcc5d22d6226f7647b"
          }
          */
         
        return res;
    } catch (error) {
      console.error(error);
      throw error;
    }
  };

  // Create the query
  const query = createQuery({
    queryKey: ['posts'],
    queryFn: fetchPaginatedPosts,
    initialData: null,
  });

  // Access and log the posts data
  const result = $query.data
  console.info({result})
</script>

<!--html omitted-->

🤔 А знаете ли вы, что...
Svelte обеспечивает хорошую поддержку серверного рендеринга для SEO-оптимизации.


2
132
1

Ответ:

Решено

Это немного сложнее, чем можно было подумать на первый взгляд. Чтобы оптимизировать получение данных, вам следует не только избегать дублирующих/ненужных запросов (цель вашего вопроса), но и избегать предоставления устаревших данных вашим пользователям. Короче говоря, вам нужно реализовать эффективный механизм кэширования данных ваших публикаций.

Хотя вы можете создать такой механизм вручную, используя хранилища Svelte, временные метки и т. д., Tanstack, создатели react-query, выпустили библиотеку запросов и кэширования для Svelte, которая будет обрабатывать сложные детали запуска эффективного кэширования за вас и сделать вашу жизнь намного проще.

Tanstack также опубликовал несколько примеров использования, которые могут оказаться очень полезными при реализации вашего собственного варианта использования.

Если вы по-прежнему предпочитаете идти по ручному маршруту, я думаю этот другой ТАК-ответ может оказаться хорошей отправной точкой.

Надеюсь, вы найдете это полезным. Удачи!