Optymalizacja odświeżania danych w Next.js: Przewodnik po rewalidacji przy użyciu Medusa.js

Autor Viktor Holik

Featured image

Witamy w naszym przewodniku dotyczącym konfiguracji rewalidacji w aplikacji Next.js przy użyciu serwera wewnętrznego. W tym tutorialu omówimy różne typy rewalidacji i sposoby zwiększenia ich bezpieczeństwa.

Do tej demonstracji skorzystamy z serwera backend Medusa.js, jednak możesz użyć dowolnego serwera backend.

Dlaczego rewalidacja jest niezbędna?

Rewalidacja jest niezbędna, aby uniknąć pobierania danych ze źródła przy każdym żądaniu, co zwiększa wydajność aplikacji internetowej. Domyślnie Next.js buforuje żądania przy użyciu metody fetch, w tym żądania POST. Bez rewalidacji lub rezygnacji z danych cache, Twoja aplikacja stałaby się statyczna.

Dwa typy rewalidacji:

Rewalidacja oparta na czasie

Rewalidacja oparta na czasie to proste podejście do ustawiania czasów życia cashe, dla danych w aplikacji Next.js. Określając interwał (w milisekundach), określasz, jak długo dane w pamięci podręcznej mają być uważane za ważne. Oto, jak możesz to wdrożyć:

fetch('https://example.pl/api/products', { next: { revalidate: 3600 } })

W tym przykładzie opcja rewalidacji jest ustawiona na 3600 sekund (1 godzina). Oznacza to, że dane pobrane z danego punktu końcowego API będą uznawane za świeże przez maksymalnie 1 godzinę. Po upływie tego okresu zostanie złożona nowa prośba o odświeżenie danych.

Alternatywnie możesz użyć właściwości revalidate na stronie lub w samym pliku komponentu:

// app/products/page.tsx

export const revalidate = 3600 // rewaliduj co najwyżej co godzinę

To podejście jest szczególnie przydatne, gdy chcesz okresowo aktualizować pamięć podręczną, zapewniając, że aplikacja obsługuje stosunkowo nowe dane, bez obciążania serwera ciągłymi żądaniami.

Rewalidacja na żądanie

Rewalidacja na żądanie zapewnia elastyczność odświeżania danych tylko wtedy, gdy jest to potrzebne. Można to osiągnąć za pomocą znaczników cashe, określonych ścieżek wewnątrz akcji serwera lub route handler. Oto jak możesz to ustawić:

export default async function Page() {
  const res = await fetch(
    'https://example.pl/api/products', 
    { next: { tags: ['products'] } } // Here is where the magic happens
  ) 
  const data = await res.json()

  return (
  ...
}

Stwórzmy route handler w Next.js, aby to przetestować:

// app/api/revalidate/[tag]/route.ts

export async function POST(
  request: NextRequest,
  { params }: { params: { tag: string } }
) {
  const tag = params.tag

  revalidateTag(tag);

  return NextResponse.json({ revalidated: tag });
}

Gdy uzyskamy dostęp do route przy użyciu adresu URL http://localhost:3000/api/revalidate/products, wyczyścimy cache i pobierzemy ponownie najnowsze dane.

Implementacja rewalidacji z serwerem wewnętrznym

Ulepszmy route handler, dodając tajny klucz do parametrów zapytania. Dzięki temu tylko autoryzowani użytkownicy będą mogli ręcznie uruchomić proces rewalidacji.

// app/api/revalidate/[tag]/route.ts

export async function POST(
  request: NextRequest,
  { params }: { params: { tag: string } }
) {
  const tag = params.tag
  // Retrieve secret key from search params
  const secret = request.nextUrl.searchParams.get('secret');

  // Verify secret key
  if (secret !== process.env.REVALIDATE_SECRET) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
  }

  revalidateTag(tag);

  return NextResponse.json({ revalidated: tag });
}

Dodaj również REVALIDATE_SECRET do swoich zmiennych środowiskowych:

// .env
REVALIDATE_SECRET=supersecret_revalidate_key

Teraz przejdźmy do naszego serwera (zakładając, że korzystamy z Medusa.js) i zaimplementujmy subskrybenta dla każdej aktualizacji produktu.

// src/subscribers/product.ts
import axios from "axios";

class ProductSubscriber {
  constructor({ eventBusService }) {
    eventBusService.subscribe(
      "product.created",
      this.revalidateOnDemand
    );
    eventBusService.subscribe(
      "product.updated",
      this.revalidateOnDemand
    );
    eventBusService.subscribe(
      "product.deleted",
      this.revalidateOnDemand
    );
  }

  revalidateOnDemand = async () => {
    await axios.post(process.env.FRONTEND_REVALIDATE_URL/products, {
      params: {
        secret: process.env.FRONTEND_REVALIDATE_SECRET
      },
    });
  };
}

export default ProductSubscriber;

Podsumowanie

Wykorzystując te strategie, można osiągnąć równowagę pomiędzy optymalizacją wydajności i świeżością danych. Dodanie tajnego klucza do parametrów adresu URL zapewnia, że tylko autoryzowani użytkownicy mogą uruchomić ręczną rewalidacje, co zwiększa bezpieczeństwo aplikacji.

Mam nadzieję, że ten artykuł okazał się pomocny.

Masz pytania lub potrzebujesz pomocy z rewalidacją w Next.js?

Skontaktuj się z nami

Inne posty na blogu

Maintance mode w aplikacjach Next.js

Jak zaimplementować maintenance mode w Next.js? Czy jest to równie proste, co kilkuminutowa konfiguracja wtyczki w WordPress’ie? Oczywiście, że tak!

Medusa vs Magento: Całkowity koszt posiadania

Magento, w porównaniu do Medusy, może prowadzić do wyższych kosztów długoterminowych z powodu swojej licencji oraz ryzyka związanego ze stopniowym spadkiem popularności języka PHP...

Opowiedz nam o swoim projekcie

Myślisz o nowym projekcie? Zrealizujmy go!

Naciskając „Wyślij wiadomość” udzielasz nam, tj. Rigby, zgody na email marketing naszych usług w ramach komunikacji dotyczącej Twojego projektu. Zgodę możesz wycofać, np. pisząc na adres hello@rigbyjs.com.
Więcej
placeholder

Grzegorz Tomaka

Co-CEO & Co-founder

LinkedIn icon
placeholder

Jakub Zbaski

Co-CEO & Co-founder

LinkedIn icon