API Deposu
PazaryeriKataloğa gitBlogMCPTest LabAPI EkleDestek OlGitHub
Blog'a dön
Rehberler
TUTORIAL
open-meteo
EN

Open-Meteo ve Next.js ile Hava Durumu Widget'ı Yapımı

API anahtarı gerektirmeyen Open-Meteo API ile server-rendered, cache'li ve hata toleranslı bir Next.js hava durumu widget'ı tasarlama rehberi.

25 Nis 20263 dk okuma508 kelime
Yazar:Mert Murat

Mert Murat, API Deposu'nu kurdu ve sürdürüyor. Katalogdaki 400'ü aşkın herkese açık API kaydını sağlayıcıların resmî dokümantasyonuna karşı doğruluyor, uygun olanlarda endpoint'leri çalıştırarak test ediyor ve blogdaki rehberleri yazıyor. Düzeltme ve önerileri iletisim@apideposu.com adresine iletebilirsiniz.

İnceleme yöntemi: Temel iddialar, bağlantı verilen sağlayıcı belgeleri ve ilgili API Deposu katalog kayıtlarıyla karşılaştırıldı. Editoryal politikayı incele

Hazırlanışı: Taslak aşamasında yapay zekâ desteği kullanılabilir. Yayımdan önce her iddia, yazıda bağlantı verilen resmî sağlayıcı belgelerine ve katalog kayıtlarına karşı bir editör tarafından kontrol edilir; doğrulanamayan bilgi yayımlanmaz.

Open-Meteo ve Next.js ile Hava Durumu Widget'ı Yapımı cover image

Bir hava durumu widget'ı küçük görünür ama gerçek bir API entegrasyonunda ihtiyaç duyulan temel kararların çoğunu içerir: istek nereye atılacak, veri ne kadar cache'lenecek, hata olursa kullanıcı ne görecek ve yanıt formatı değişirse uygulama nasıl davranacak?

Bu rehberde API Deposu'ndaki Open-Meteo kaydını temel alarak Next.js App Router içinde server-rendered bir widget tasarlıyoruz. Open-Meteo'nun avantajı, tipik geliştirme ve düşük hacimli kullanımda API anahtarı gerektirmeden çalışmasıdır.

Ne inşa ediyoruz?

Bir Next.js server component şu işi yapacak:

  • Enlem ve boylamla Open-Meteo forecast endpoint'ine istek atacak.
  • Güncel sıcaklık, rüzgâr hızı ve WMO hava kodunu doğrulayacak.
  • Başarılı yanıtı 10 dakika yeniden doğrulama süresiyle cache'leyecek.
  • Ağ veya veri hatasında sayfanın geri kalanını bozmadan bir geri dönüş gösterecek.

Örnek konum İstanbul olsa da aynı yardımcı fonksiyon başka koordinatlarla da kullanılabilir.

Endpoint şekli

Open-Meteo belgelerinde güncel değerler, forecast endpoint'inin current parametresiyle seçilir. Bu rehberin isteği şu şekildedir:

txt
GET https://api.open-meteo.com/v1/forecast
  ?latitude=41.0082
  &longitude=28.9784
  &current=temperature_2m,wind_speed_10m,weather_code
  &temperature_unit=celsius
  &wind_speed_unit=kmh

Yanıtın current nesnesinde temperature_2m, wind_speed_10m ve weather_code alanlarını bekliyoruz. Sıcaklık ve rüzgâr birimini sorguda açıkça belirlemek, UI'daki °C ve km/sa etiketlerinin sağlayıcı varsayımlarına bağlı kalmasını engeller. TypeScript tipi yazmak tek başına dış veriyi güvenli yapmaz; JSON çalışma anında yine unknown kabul edilip kontrol edilmelidir.

Cache'li ve doğrulamalı fetch yardımcısı

Sağlayıcı erişimini UI bileşeninden ayırın. Aşağıdaki yardımcı; koordinatları, HTTP durumunu ve üç sayısal alanı kontrol eder. Beş saniyelik timeout da yanıt vermeyen isteğin sayfa render'ını süresiz bekletmesini önler.

ts
// src/lib/weather.ts
export type CurrentWeather = {
  temperature: number;
  windSpeed: number;
  weatherCode: number;
};

function isFiniteNumber(value: unknown): value is number {
  return typeof value === "number" && Number.isFinite(value);
}

export async function getCurrentWeather(
  latitude: number,
  longitude: number,
): Promise<CurrentWeather | null> {
  if (
    !Number.isFinite(latitude) || latitude < -90 || latitude > 90
    || !Number.isFinite(longitude) || longitude < -180 || longitude > 180
  ) {
    throw new Error("Geçersiz koordinat.");
  }

  const url = new URL("https://api.open-meteo.com/v1/forecast");
  url.searchParams.set("latitude", String(latitude));
  url.searchParams.set("longitude", String(longitude));
  url.searchParams.set(
    "current",
    "temperature_2m,wind_speed_10m,weather_code",
  );
  url.searchParams.set("temperature_unit", "celsius");
  url.searchParams.set("wind_speed_unit", "kmh");

  try {
    const response = await fetch(url, {
      next: { revalidate: 600 },
      signal: AbortSignal.timeout(5_000),
    });

    if (!response.ok) return null;

    const payload: unknown = await response.json();
    if (!payload || typeof payload !== "object") return null;

    const current = (payload as { current?: unknown }).current;
    if (!current || typeof current !== "object") return null;

    const values = current as Record<string, unknown>;
    if (
      !isFiniteNumber(values.temperature_2m)
      || !isFiniteNumber(values.wind_speed_10m)
      || !isFiniteNumber(values.weather_code)
    ) {
      return null;
    }

    return {
      temperature: values.temperature_2m,
      windSpeed: values.wind_speed_10m,
      weatherCode: values.weather_code,
    };
  } catch {
    return null;
  }
}

next: { revalidate: 600 }, Next.js veri cache'inin uygun olduğu üretim akışında aynı URL için yanıtı 600 saniye yeniden kullanır. Koordinatlar URL'nin parçası olduğu için farklı şehirler ayrı cache girdileri oluşturur. Cache süresini ürününüzün tazelik ihtiyacına göre belirleyin; bu örnekteki 10 dakika evrensel bir meteoroloji kuralı değildir.

Koordinatlar serbest kullanıcı girdisinden geliyorsa her küçük ondalık farkı yeni bir URL ve cache anahtarı üretir. Şehir tabanlı bir widget'ta önceden tanımlı koordinatlar kullanmak veya ürünün ihtiyaç duyduğu hassasiyete göre koordinatları normalize etmek, gereksiz cache çeşitlenmesini azaltır. Bu normalizasyonu yapmadan önce konum hassasiyetinin kullanım amacına etkisini değerlendirin.

Hava kodunu kullanıcı diline çevirin

Open-Meteo weather_code alanında WMO kodları döndürür. UI içinde ham 3 değerini göstermek yerine kullandığınız kodları etiketleyin ve bilinmeyen değer için açık bir varsayılan bırakın.

ts
// src/lib/weather-codes.ts
const WEATHER_LABELS: Record<number, string> = {
  0: "Açık",
  1: "Çoğunlukla açık",
  2: "Parçalı bulutlu",
  3: "Kapalı",
  45: "Sisli",
  61: "Hafif yağmurlu",
  63: "Yağmurlu",
  65: "Kuvvetli yağmurlu",
  71: "Hafif kar yağışlı",
  73: "Kar yağışlı",
  95: "Gök gürültülü fırtına",
};

export function describeWeather(code: number): string {
  return WEATHER_LABELS[code] ?? "Durum bilinmiyor";
}

Üretimde desteklemek istediğiniz WMO kodlarının tamamını Open-Meteo belgelerindeki tabloyla eşleştirin.

Server component içinde kullanım

tsx
// src/components/weather-widget.tsx
import { describeWeather } from "@/lib/weather-codes";
import { getCurrentWeather } from "@/lib/weather";

type WeatherWidgetProps = {
  city: string;
  latitude: number;
  longitude: number;
};

export async function WeatherWidget(props: WeatherWidgetProps) {
  const weather = await getCurrentWeather(props.latitude, props.longitude);

  if (!weather) {
    return <p role="status">Hava durumu şu anda alınamıyor.</p>;
  }

  return (
    <section aria-label={`${props.city} hava durumu`}>
      <strong>{props.city}</strong>
      <p>{Math.round(weather.temperature)} °C</p>
      <p>
        {describeWeather(weather.weatherCode)} ·{" "}
        {Math.round(weather.windSpeed)} km/sa
      </p>
    </section>
  );
}

Bir sayfada kullanım da doğrudan sunucu bileşeni olarak yapılır:

tsx
<WeatherWidget
  city="İstanbul"
  latitude={41.0082}
  longitude={28.9784}
/>

Hata ve üretim sınırları

Yardımcı bir pazarlama kartında null veya kısa bir "alınamıyor" durumu yeterli olabilir. Operasyonel karar veren bir ekranda ise hata türünü sunucu loguna aktarın, son başarılı verinin ne kadar eski olduğunu gösterin ve gerekiyorsa sözleşmesi uygun ikinci bir sağlayıcı tasarlayın. Sessiz fallback kullanmak, kesintiyi hiç izlememek anlamına gelmemelidir.

Open-Meteo çağrısını tek bir yardımcı sınırında tutmak; cache süresini, birimleri, timeout'u veya sağlayıcıyı UI'ı yeniden yazmadan değiştirmeyi sağlar. Kritik meteoroloji kullanımında bu örnek tek başına yeterlilik ya da doğruluk garantisi vermez.

Örnekte ağ hatası, timeout, HTTP hatası ve şema hatası aynı null sonucuna indirgenir; yardımcı bir kart için bu bilinçli bir sadeliktir. Dashboard gibi izlenmesi gereken bir yüzeyde { ok: true, data } ve { ok: false, reason } biçiminde ayrımlı bir sonuç döndürün. Böylece kullanıcıya güvenli bir genel mesaj gösterirken ölçümlerde sağlayıcı kesintisini geçersiz yanıttan ayırabilirsiniz. Bu ayrım, yalnızca yeniden denemeyle düzelebilecek hatalara retry uygulamanızı da kolaylaştırır.

İlgili API Deposu kayıtları

  • Open-Meteo

Kaynaklar

  • https://open-meteo.com/en/docs

Sık Sorulan Sorular

›Open-Meteo için API anahtarı gerekiyor mu?

Hayır. Open-Meteo geliştirme ve düşük hacimli kullanım için API anahtarı olmadan çalışabilen nadir hava durumu API'lerinden biridir.

›Hava durumu verisini ne kadar sık yenilemeliyim?

Pazarlama sayfası veya dashboard widget'ı için 10-15 dakikalık cache çoğu durumda yeterlidir. Her sayfa görüntülemede API çağırmak gereksiz yük oluşturur.

›Widget frontend'de mi backend'de mi veri çekmeli?

Next.js server component ile sunucuda çekmek cache kontrolünü kolaylaştırır ve ilk yüklemede içeriği hazır gösterir. Client-side fetch de mümkündür, ancak cache ve hata yönetimi ayrıca düşünülmelidir.

Yazı bilgisi

dk okuma3
kelime508
İlgili API'ler1

İlgili API'ler

open-meteo

Kaynaklar

Open-Meteo documentation

https://open-meteo.com/en/docs

Benzer yazılar

Tüm blog yazılarını gör
Okumaya devam et
Ücretsiz Döviz API'si ile Kur Çevirici Yapımı cover image

Ücretsiz Döviz API'si ile Kur Çevirici Yapımı

Repo-hosted ücretsiz döviz kuru API'siyle küçük bir kur çevirici tasarlarken cache, doğrulama ve üretim risklerini nasıl ele almalısınız?

Okumaya devam et
API Anahtarı Güvenliği ve Rate Limit Rehberi cover image

API Anahtarı Güvenliği ve Rate Limit Rehberi

API anahtarlarını frontend'de sızdırmadan, rate limitleri merkezi yöneterek ve sağlayıcı hatalarını normalize ederek daha güvenli entegrasyonlar kurun.

Okumaya devam et
Geliştiriciler İçin En İyi Ücretsiz Hava Durumu API'leri cover image

Geliştiriciler İçin En İyi Ücretsiz Hava Durumu API'leri

API anahtarı, kredi kartı ve ücretli plan baskısı olmadan kullanılabilecek hava durumu API'lerini kapsam, doğrulama ve üretim riski açısından karşılaştırın.

Daha fazla API rehberi keşfet

API Deposu blogunda katalog verisine dayalı karşılaştırmalar, listeler ve entegrasyon rehberleri bulabilirsin.

Tüm blog yazılarını gör

API Deposu

Bu katalog, 20 Ağustos 2026 itibarıyla doğrulanmış açık kaynaklardan derlenmiştir. Entegrasyondan önce resmi dokümantasyonu kontrol edin.

iletisim@apideposu.com

Güven ve içerik

HakkındaEditoryal politikaİletişimDestek olTeşekkürler

Yasal ve tercihler

Kullanım ŞartlarıGizlilikÇerezlerX