Bu ders için video bulunmamaktadır.

Bu derse başlamak veya ilerlemenizi kaydetmek için lütfen giriş yapın veya kayıt olun.

Ders İçeriği

RESTful API Nedir?

REST (Representational State Transfer), web servisleri geliştirmek için kullanılan bir mimari stildir. RESTful API'ler, HTTP protokolünü kullanarak kaynaklara (resources) erişim sağlar ve bu kaynaklar üzerinde CRUD (Create, Read, Update, Delete) operasyonları yapılmasına olanak tanır.

RESTful API İlkeleri

  • **Kaynaksal (Resource-Based):** Her şey bir kaynak olarak kabul edilir ve benzersiz bir URI (Uniform Resource Identifier) ile temsil edilir.
  • **Durumsuz (Stateless):** Her istek, sunucunun önceki istekler hakkında bilgi tutmasına gerek kalmadan, istemciden sunucuya gerekli tüm bilgiyi içermelidir.
  • **İstemci-Sunucu (Client-Server):** İstemci ve sunucu birbirinden bağımsızdır.
  • **Katmanlı Sistem (Layered System):** Bir istemci, doğrudan bir sunucuya bağlı olup olmadığını veya isteklerinin bir ara sunucu aracılığıyla iletilip iletilmediğini bilemez.
  • **Önbelleklenebilir (Cacheable):** Yanıtlar, istemci tarafında önbelleğe alınabilir olarak işaretlenebilir.
  • **Tek Tip Arayüz (Uniform Interface):** Kaynaklarla etkileşim kurmak için standart bir yöntem (HTTP metotları) kullanılır.

JWT (JSON Web Tokens) ile Kimlik Doğrulama

JWT, güvenli bir şekilde bilgi alışverişi yapmak için kullanılan kompakt, URL güvenli bir yöntemdir. Genellikle API kimlik doğrulama ve yetkilendirme için kullanılır.

JWT Yapısı

Bir JWT üç bölümden oluşur ve noktalarla ayrılır:

  1. **Header (Başlık):** Token türünü (JWT) ve kullanılan imzalama algoritmasını (örn. HS256, RS256) içerir.
  2. **Payload (Yük):** Kullanıcı bilgileri (örn. kullanıcı ID, rol) ve diğer verileri (claims) içerir. Hassas bilgiler içermemelidir.
  3. **Signature (İmza):** Header ve Payload'ın base64url kodlanmış hallerinin, bir sır (secret) anahtar kullanılarak imzalanmasıyla oluşturulur. Bu, token'ın bütünlüğünü doğrular.

JWT Kullanımı

npm install jsonwebtoken bcryptjs
const jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");

const SECRET_KEY = "cokgizlianahtar"; // Gerçek uygulamada ortam değişkeninden alınmalı

// Kullanıcı kaydı (şifre hashleme)
async function registerUser(username, password) {
  const hashedPassword = await bcrypt.hash(password, 10);
  // Kullanıcıyı veritabanına kaydet
  console.log(`Kullanıcı ${username} kaydedildi. Hashlenmiş şifre: ${hashedPassword}`);
  return { username, hashedPassword };
}

// Kullanıcı girişi (token oluşturma)
async function loginUser(username, password) {
  // Kullanıcıyı veritabanından bul
  const user = { username: "testuser", hashedPassword: "$2a$10$abcdefghijklmnopqrstuv" }; // Örnek kullanıcı

  const isPasswordValid = await bcrypt.compare(password, user.hashedPassword);

  if (isPasswordValid) {
    const token = jwt.sign({ username: user.username }, SECRET_KEY, { expiresIn: "1h" });
    console.log("Giriş başarılı! Token:", token);
    return token;
  } else {
    console.log("Geçersiz kullanıcı adı veya şifre.");
    return null;
  }
}

// Token doğrulama middleware
function authenticateToken(req, res, next) {
  const authHeader = req.headers["authorization"];
  const token = authHeader && authHeader.split(" ")[1];

  if (token == null) return res.sendStatus(401); // Token yok

  jwt.verify(token, SECRET_KEY, (err, user) => {
    if (err) return res.sendStatus(403); // Geçersiz token
    req.user = user;
    next();
  });
}

// Örnek Kullanım
// (async () => {
//   await registerUser("testuser", "password123");
//   const token = await loginUser("testuser", "password123");
//   // Token ile korunan bir rotayı test etmek için:
//   // app.get("/protected", authenticateToken, (req, res) => {
//   //   res.json({ message: `Hoş geldiniz, ${req.user.username}!` });
//   // });
// })();

API Güvenliği

API'lerinizi güvende tutmak, uygulamanızın bütünlüğü ve kullanıcı verilerinin korunması için hayati öneme sahiptir. İşte bazı temel güvenlik önlemleri:

CORS (Cross-Origin Resource Sharing)

CORS, bir web sayfasında çalışan bir web uygulamasının, farklı bir kaynaktan (domain, protokol veya port) kaynaklara erişmesine izin veren bir güvenlik mekanizmasıdır. Express.js'te cors middleware'i ile kolayca yönetilebilir.

npm install cors
const express = require("express");
const cors = require("cors");
const app = express();

app.use(cors()); // Tüm kaynaklardan gelen isteklere izin ver

// Belirli kaynaklara izin ver
// app.use(cors({
//   origin: ["http://localhost:3000", "https://myfrontend.com"],
//   methods: ["GET", "POST"],
//   allowedHeaders: ["Content-Type", "Authorization"]
// }));

app.get("/data", (req, res) => {
  res.json({ message: "Bu veri CORS tarafından korunuyor!" });
});

app.listen(3000, () => console.log("Sunucu 3000 portunda çalışıyor"));

HTTPS Kullanımı

API trafiğini şifrelemek için HTTPS kullanmak zorunludur. Üretim ortamında SSL/TLS sertifikaları ile sunucunuzu yapılandırmalısınız. Geliştirme ortamında `self-signed` sertifikalar kullanabilirsiniz.

Input Validation (Girdi Doğrulama)

Kullanıcıdan gelen tüm girdileri sunucu tarafında doğrulamak, güvenlik açıklarını (örn. SQL Injection, XSS) önlemek için kritik öneme sahiptir. `express-validator` gibi kütüphaneler bu konuda yardımcı olur.

npm install express-validator
const express = require("express");
const { body, validationResult } = require("express-validator");
const app = express();

app.use(express.json());

app.post(
  "/register",
  [
    body("username").isLength({ min: 5 }).withMessage("Kullanıcı adı en az 5 karakter olmalı"),
    body("email").isEmail().withMessage("Geçerli bir e-posta adresi girin"),
    body("password").isLength({ min: 6 }).withMessage("Şifre en az 6 karakter olmalı"),
  ],
  (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    // Veriler geçerli, kullanıcıyı kaydet
    res.status(201).json({ message: "Kullanıcı başarıyla kaydedildi!" });
  }
);

app.listen(3000, () => console.log("Sunucu 3000 portunda çalışıyor"));

Rate Limiting (Hız Sınırlama)

Rate limiting, belirli bir zaman diliminde bir istemcinin API'nize yapabileceği istek sayısını sınırlamak için kullanılır. Bu, kötü niyetli saldırıları (örn. Brute-force, DDoS) önlemeye yardımcı olur. `express-rate-limit` kütüphanesi yaygın olarak kullanılır.

npm install express-rate-limit
const express = require("express");
const rateLimit = require("express-rate-limit");
const app = express();

// 15 dakikada aynı IP'den en fazla 100 istek
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 dakika
  max: 100, // Her IP için 15 dakikada 100 istek
  message: "Çok fazla istek gönderdiniz, lütfen daha sonra tekrar deneyin.",
});

// Tüm API isteklerine rate limiter uygula
app.use(limiter);

app.get("/api/data", (req, res) => {
  res.json({ message: "Veri başarıyla alındı!" });
});

app.listen(3000, () => console.log("Sunucu 3000 portunda çalışıyor"));

API Dokümantasyonu

API dokümantasyonu, API'nizin nasıl kullanılacağını açıklayan önemli bir kaynaktır. Geliştiricilerin API'nizi kolayca anlamasına ve entegre etmesine yardımcı olur. Swagger (OpenAPI) en popüler dokümantasyon araçlarından biridir.

Swagger (OpenAPI) Kullanımı

npm install swagger-ui-express yamljs

swagger.yaml veya swagger.json dosyanızı oluşturun ve Express uygulamanızda sunun:

const express = require("express");
const swaggerUi = require("swagger-ui-express");
const YAML = require("yamljs");
const app = express();

// Swagger YAML dosyasını yükle
const swaggerDocument = YAML.load("./swagger.yaml");

// Swagger UI'ı /api-docs yolunda sun
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerDocument));

app.get("/", (req, res) => {
  res.send("API Dokümantasyonu için /api-docs adresine gidin.");
});

app.listen(3000, () => console.log("Sunucu 3000 portunda çalışıyor"));

Örnek swagger.yaml içeriği:

openapi: 3.0.0
info:
  title: My Simple API
  version: 1.0.0
paths:
  /users:
    get:
      summary: Get all users
      responses:
        '200':
          description: A list of users.
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: integer
                    name:
                      type: string

Bilgi Kontrolü: RESTful API Geliştirme

Pratik Alıştırma: Basit Bir Ürün API'si

Bu alıştırmada, Express.js kullanarak basit bir ürün API'si oluşturacaksınız. API aşağıdaki özelliklere sahip olmalıdır:

  • Tüm ürünleri listeleme (GET /api/products)
  • Belirli bir ürünü ID'ye göre getirme (GET /api/products/:id)
  • Yeni ürün ekleme (POST /api/products)
  • Mevcut bir ürünü güncelleme (PUT /api/products/:id)
  • Ürün silme (DELETE /api/products/:id)
  • JWT ile kimlik doğrulama (örneğin, ürün ekleme/güncelleme/silme rotaları için)
  • Girdi doğrulama (validation)