Aynı Sunucuda REST ve Gerçek Zamanlı İletişim Protokollerini (Örn: WebSockets) Birlikte Sunma Rehberi
Günümüz modern web uygulamaları, farklı iletişim ihtiyaçlarına yönelik çeşitli protokoller kullanmaktadır. Geleneksel olarak kaynak tabanlı veri alışverişi için RESTful API’ler tercih edilirken, gerçek zamanlı etkileşimler, bildirimler veya anlık veri akışları için WebSockets gibi çift yönlü iletişim protokolleri öne çıkar. Bu rehberde, bir uygulamanın hem REST API’sini hem de gerçek zamanlı iletişim protokollerini (bu makalede “MCP” terimi yerine yaygın bir örnek olarak WebSockets’ı ele alacağız) aynı sunucu üzerinde nasıl verimli bir şekilde barındırılacağını, mimari yaklaşımları, uygulama örneklerini ve dikkat edilmesi gerekenleri detaylı bir şekilde inceleyeceğiz.
REST ve WebSockets Arasındaki Temel Farklar
REST (Representational State Transfer) ve WebSockets, web tabanlı uygulamalarda veri alışverişi için kullanılan iki farklı ancak tamamlayıcı yaklaşımdır. Her birinin kendine özgü avantajları ve kullanım senaryoları bulunur.
REST API’nin Özellikleri ve Kullanım Alanları
REST API’ler, HTTP protokolü üzerine inşa edilmiş, durum bilgisiz (stateless) ve kaynak tabanlı bir mimari stilidir. Her istek, sunucunun istemcinin önceki istekleri hakkında herhangi bir bilgiye sahip olmamasını gerektirir. Bu durum, API’leri ölçeklenebilir ve hata toleranslı hale getirir. Genellikle CRUD (Create, Read, Update, Delete) operasyonları için kullanılırlar.
- Durum Bilgisiz (Stateless): Her istek, sunucunun işlemi tamamlaması için gerekli tüm bilgiyi içerir.
- Önbelleklenebilir (Cacheable): Yanıtlar istemci tarafında veya ara sunucularda önbelleğe alınabilir.
- Katmanlı Sistem (Layered System): Yük dengeleyiciler, proxy’ler gibi ara katmanlar kullanılabilir.
- Kullanım Alanları: Blog yazıları, e-ticaret ürün listeleri, kullanıcı profilleri gibi statik veya yarı statik verilerin alınması, gönderilmesi ve güncellenmesi.
WebSockets’ın Özellikleri ve Kullanım Alanları
WebSockets, istemci ile sunucu arasında tam çift yönlü, kalıcı bir bağlantı sağlayan bir iletişim protokolüdür. HTTP el sıkışması ile başlar, ancak daha sonra HTTP’den bağımsız, düşük gecikmeli bir bağlantıya yükseltilir. Bu bağlantı açık kaldığı sürece, hem istemci hem de sunucu birbirlerine veri gönderebilir.
- Çift Yönlü (Full-Duplex): Hem istemci hem de sunucu aynı anda veri gönderebilir ve alabilir.
- Kalıcı Bağlantı: Bir kez kurulan bağlantı, kapatılana kadar açık kalır, her mesaj için yeni bir bağlantı kurma maliyeti yoktur.
- Düşük Gecikme: Gerçek zamanlı uygulamalar için idealdir.
- Kullanım Alanları: Anlık mesajlaşma uygulamaları, canlı bildirimler, oyunlar, hisse senedi takip sistemleri, canlı konum takibi.
Neden Birlikte Kullanım İhtiyacı Doğar?
Modern uygulamalar genellikle hem veritabanından veri çekme ve güncelleme (REST) hem de anlık etkileşimler (WebSockets) gerektirir. Örneğin, bir sosyal medya uygulaması, kullanıcı profilini ve gönderileri REST API aracılığıyla yönetirken, anlık mesajlaşma ve bildirimler için WebSockets kullanabilir. Bu iki farklı protokolü aynı sunucuda barındırmak, altyapı yönetimini basitleştirir, maliyetleri düşürür ve uygulama entegrasyonunu kolaylaştırır.
Aynı Sunucuda Birlikte Çalıştırma Yaklaşımları
REST ve WebSockets’ı aynı sunucuda barındırmak için farklı mimari yaklaşımlar mevcuttur. Seçiminiz, projenizin karmaşıklığına, ölçeklenebilirlik ihtiyaçlarına ve kullanılan teknoloji yığınına bağlı olacaktır.
Tek Sunucu, Farklı Portlar
Bu, en basit yaklaşımlardan biridir. REST API’niz bir portta (örneğin 8080), WebSocket sunucunuz ise başka bir portta (örneğin 8081) çalışır. İstemciler, ihtiyaç duydukları protokole göre ilgili porta bağlanır.
- Avantajlar: Kurulumu kolaydır, birbirinden bağımsız çalışırlar.
- Dezavantajlar: Güvenlik duvarı ayarları gerektirebilir, istemci tarafında farklı portları yönetmek gerekebilir.
Tek Sunucu, Aynı Port Üzerinde Path Bazlı Yönlendirme
Bu yaklaşımda, hem REST hem de WebSockets aynı port üzerinde çalışır, ancak farklı URL yolları (path) kullanırlar. Örneğin, /api yolu REST istekleri için kullanılırken, /ws yolu WebSocket bağlantıları için kullanılır. Bu, genellikle bir ters proxy (reverse proxy) veya uygulama sunucusunun kendisi tarafından yönetilir.
- Avantajlar: Tek bir port üzerinden erişim, güvenlik duvarı sorunlarını azaltır.
- Dezavantajlar: Yapılandırma biraz daha karmaşık olabilir.
Reverse Proxy Kullanımı (Nginx/Apache)
Bir ters proxy (örneğin Nginx veya Apache), istemci isteklerini alır ve bunları uygun arka uç hizmetine (REST API veya WebSocket sunucusu) yönlendirir. Bu, özellikle aynı port üzerinde farklı yollarla erişim sağlamak için güçlü bir yöntemdir ve SSL sonlandırma, yük dengeleme gibi ek avantajlar sunar.
- Avantajlar: Merkezi trafik yönetimi, SSL sonlandırma, yük dengeleme, güvenlik katmanı sağlar.
- Dezavantajlar: Ek bir bileşen ve yapılandırma gerektirir.
Ortak Bir Framework ile Yönetim (Node.js Express/Socket.IO, Python Flask/Flask-SocketIO)
Bazı web framework’leri, hem HTTP (REST) hem de WebSocket sunucularını aynı uygulama içinde kolayca entegre etme yeteneği sunar. Örneğin, Node.js’te Express ve Socket.IO veya Python’da Flask ve Flask-SocketIO bu tür entegrasyonları basitleştirir.
- Avantajlar: Tek bir kod tabanında yönetim, kolay entegrasyon.
- Dezavantajlar: Framework’ün yetenekleriyle sınırlı olabilir.
Uygulama Geliştirme Ortamının Hazırlanması
Uygulamanızı geliştirmeye başlamadan önce, gerekli araçları ve ortamı kurmanız önemlidir. Bu bölümde, örnek bir Node.js tabanlı uygulama için ortam kurulumunu ele alacağız.
Gerekli Yazılımların Kurulumu
Örneğimiz için Node.js, npm (Node Package Manager) ve bir ters proxy olarak Nginx’e ihtiyacımız olacak.
- Node.js ve npm: nodejs.org adresinden işletim sisteminize uygun sürümü indirip kurun. Kurulumdan sonra terminalde
node -vvenpm -vkomutlarını çalıştırarak doğruluğunu kontrol edebilirsiniz. - Nginx: Linux dağıtımlarında genellikle paket yöneticileri aracılığıyla (örn:
sudo apt install nginx), diğer işletim sistemlerinde ise resmi web sitesinden (nginx.org) indirilebilir.
Proje Yapısının Oluşturulması
Yeni bir Node.js projesi başlatarak temel dosya yapısını oluşturalım.
mkdir rest-websocket-app
cd rest-websocket-app
npm init -y
Bu komutlar, projeniz için bir dizin oluşturacak ve temel bir package.json dosyası başlatacaktır.
Bağımlılıkların Yönetimi
REST API için Express ve WebSocket iletişimi için Socket.IO kütüphanelerini kuracağız.
npm install express socket.io
Bu komut, express ve socket.io paketlerini projenize bağımlılık olarak ekleyecektir.
Örnek Uygulama: Node.js ile REST ve WebSockets
Şimdi, Node.js ve Express/Socket.IO kullanarak hem REST API hem de WebSocket sunucusunu aynı uygulama içinde nasıl entegre edeceğimize dair basit bir örnek oluşturalım.
Express ile REST API Oluşturma
app.js adında bir dosya oluşturalım ve içine basit bir Express REST API ekleyelim.
// app.js - REST API kısmı
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
app.use(express.json()); // JSON body parsing için
// Basit bir REST GET endpoint'i
app.get('/api/merhaba', (req, res) => {
res.json({ mesaj: 'Merhaba REST API!' });
});
// Basit bir REST POST endpoint'i
app.post('/api/gonder', (req, res) => {
const veri = req.body.veri || 'Veri yok';
console.log('REST POST isteği alındı:', veri);
res.status(200).json({ durum: 'başarılı', alınanVeri: veri });
});
// Sunucuyu başlat (şimdilik sadece REST için)
// app.listen(PORT, () => {
// console.log(REST API ${PORT} portunda çalışıyor.);
// });
Socket.IO ile WebSocket Sunucusu Kurma
Aynı app.js dosyasına Socket.IO sunucusunu entegre edelim. Socket.IO, HTTP sunucusunun üzerine kurulabilir.
// app.js - WebSocket kısmı (önceki kodun altına ekleyin)
const http = require('http');
const socketIo = require('socket.io');
// Express uygulamasını bir HTTP sunucusuna bağla
const server = http.createServer(app);
const io = socketIo(server);
// WebSocket bağlantılarını dinle
io.on('connection', (socket) => {
console.log('Yeni bir WebSocket bağlantısı kuruldu.');
// İstemciden gelen mesajları dinle
socket.on('mesajGonder', (data) => {
console.log('WebSocket mesajı alındı:', data);
// Gelen mesajı tüm bağlı istemcilere geri gönder
io.emit('yeniMesaj', Sunucudan: ${data.text});
});
// Bağlantı kesildiğinde
socket.on('disconnect', () => {
console.log('Bir WebSocket bağlantısı kesildi.');
});
});
// Sunucuyu başlat (hem REST hem de WebSocket için)
server.listen(PORT, () => {
console.log(Sunucu ${PORT} portunda çalışıyor (REST ve WebSockets).);
});
Aynı Sunucu Üzerinde Entegrasyon
Yukarıdaki kod parçacıkları, app.js dosyasında birleştirildiğinde, hem Express tabanlı REST API'nizi hem de Socket.IO tabanlı WebSocket sunucunuzu aynı Node.js sürecinde ve aynı port üzerinde çalıştıracaktır. Express uygulaması HTTP isteklerini işlerken, Socket.IO aynı HTTP sunucusu üzerinden WebSocket el sıkışmalarını ve sonraki çift yönlü iletişimi yönetir.
Bu entegrasyon, özellikle küçük ve orta ölçekli uygulamalar için oldukça verimlidir. Tek bir kod tabanı, tek bir süreç ve tek bir port üzerinden hem geleneksel API isteklerini hem de gerçek zamanlı iletişim ihtiyaçlarını karşılayabilirsiniz.
Reverse Proxy (Nginx) ile Yönlendirme
Üretim ortamlarında veya daha karmaşık senaryolarda, Nginx gibi bir ters proxy kullanmak, hem REST hem de WebSockets trafiğini yönetmek için tercih edilen bir yöntemdir. Nginx, gelen istekleri dinleyebilir ve belirli yollara veya koşullara göre farklı arka uç hizmetlerine yönlendirebilir.
Nginx Kurulumu ve Temel Yapılandırma
Nginx'i kurduktan sonra, genellikle /etc/nginx/sites-available/ dizininde bir yapılandırma dosyası oluşturmanız gerekir. Örneğin, /etc/nginx/sites-available/rest-websocket-app.
REST API için Proxy Yapılandırması
Nginx, gelen /api isteklerini Node.js uygulamanızın çalıştığı porta yönlendirecektir.
# Nginx yapılandırma dosyası (/etc/nginx/sites-available/rest-websocket-app)
server {
listen 80;
server_name your_domain.com; # Alan adınızı buraya yazın
location /api/ {
proxy_pass http://localhost:3000; # Node.js uygulamanızın portu
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Diğer statik dosyalar veya ana sayfa için
location / {
root /var/www/html; # Frontend dosyalarınızın yolu
index index.html;
try_files $uri $uri/ =404;
}
}
WebSocket için Proxy Yapılandırması
WebSockets için Nginx'in özel başlıkları (Upgrade ve Connection) doğru şekilde iletmesi gerekir. Bu, HTTP bağlantısının WebSocket'e yükseltilmesini sağlar.
# Nginx yapılandırma dosyası (devamı)
server {
listen 80;
server_name your_domain.com; # Alan adınızı buraya yazın
location /socket.io/ { # Socket.IO'nun varsayılan yolu
proxy_pass http://localhost:3000; # Node.js uygulamanızın portu
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# ... (önceki /api/ ve / location blokları)
}
Yapılandırma dosyasını kaydettikten sonra, onu sites-enabled dizinine sembolik olarak bağlayın ve Nginx'i yeniden başlatın:
sudo ln -s /etc/nginx/sites-available/rest-websocket-app /etc/nginx/sites-enabled/
sudo nginx -t # Yapılandırmayı test et
sudo systemctl restart nginx # Nginx'i yeniden başlat
Bu yapılandırma ile, your_domain.com/api/... adresine gelen istekler Node.js uygulamanızın REST API'sine, your_domain.com/socket.io/... adresine gelen istekler ise WebSocket sunucunuza yönlendirilecektir. Bu, tek bir alan adı ve port üzerinden hem REST hem de WebSocket hizmetlerini sunmanıza olanak tanır.
Güvenlik ve Performans Konuları
Herhangi bir üretim uygulaması dağıtırken güvenlik ve performans kritik öneme sahiptir. REST ve WebSockets'ı birlikte sunarken dikkat etmeniz gereken bazı noktalar şunlardır:
SSL/TLS Kullanımı
Tüm üretim uygulamaları için HTTPS kullanmak zorunludur. Nginx gibi bir ters proxy kullanarak SSL/TLS sonlandırmasını kolayca yapılandırabilirsiniz (örneğin Let's Encrypt ile). Bu, hem REST API trafiğinizi hem de WebSocket trafiğinizi şifreleyerek veri güvenliğini sağlar. WebSocket bağlantıları için wss:// protokolünü kullanmalısınız.
Kimlik Doğrulama ve Yetkilendirme
Hem REST API'niz hem de WebSocket bağlantılarınız için uygun kimlik doğrulama ve yetkilendirme mekanizmaları uygulayın. REST için genellikle JWT (JSON Web Tokens) veya oturum tabanlı kimlik doğrulama kullanılır. WebSockets için ise, bağlantı kurulurken veya ilk mesaj gönderilirken bir kimlik doğrulama token'ı (örneğin JWT) göndermek yaygın bir yaklaşımdır. Sunucu tarafında, bu token'ı doğrulayarak kullanıcının yetkilerini kontrol edebilirsiniz.
Rate Limiting ve DoS Koruması
REST API'lerinizde kötü niyetli veya aşırı istekleri engellemek için rate limiting (istek sınırlama) uygulayın. Nginx, bu konuda yerleşik yeteneklere sahiptir. WebSocket bağlantıları için de, tek bir IP adresinden gelen aşırı bağlantı girişimlerini veya mesaj akışını izleyerek DoS (Denial of Service) saldırılarına karşı koruma sağlayabilirsiniz.
Ölçeklenebilirlik İçin İpuçları
- Yük Dengeleme: Trafik arttığında, birden fazla uygulama örneğini (REST ve WebSocket) bir yük dengeleyici arkasına yerleştirin. Nginx, hem REST hem de WebSockets için yük dengeleme yapabilir.
- Durum Yönetimi: REST doğası gereği durum bilgisizdir. WebSocket'lar ise kalıcı bağlantılar kurar. Eğer WebSocket sunucunuzda oturum durumu tutuyorsanız ve birden fazla sunucu kullanıyorsanız, bu durumu Redis gibi harici bir depoda yönetmeyi düşünün (örneğin Socket.IO'nun Redis adaptörü).
- Veritabanı ve Mesaj Kuyrukları: Yüksek trafikli uygulamalarda, veritabanı işlemlerini optimize edin ve asenkron görevler için RabbitMQ veya Kafka gibi mesaj kuyrukları kullanmayı değerlendirin.
Sonuç
Aynı sunucuda hem REST API hem de gerçek zamanlı iletişim protokollerini (WebSockets gibi) barındırmak, modern web uygulamaları için yaygın ve etkili bir yaklaşımdır. Bu entegrasyon, uygulamanızın hem geleneksel veri alışverişi ihtiyaçlarını hem de anlık etkileşim gereksinimlerini tek bir altyapı üzerinden karşılamasına olanak tanır. Doğru mimariyi seçmek, güvenlik önlemlerini almak ve performansı optimize etmek, başarılı bir dağıtım için kritik öneme sahiptir. Node.js gibi teknolojiler ve Nginx gibi ters proxy'ler, bu süreci oldukça basitleştirir ve geliştiricilere güçlü, esnek çözümler sunar.
SSS (Sık Sorulan Sorular)
Neden iki farklı protokol kullanmalıyım?
REST, kaynak tabanlı, durum bilgisiz veri alışverişi için optimize edilmiştir ve genellikle CRUD operasyonları için idealdir. WebSockets ise, düşük gecikmeli, çift yönlü ve kalıcı bağlantılar gerektiren gerçek zamanlı uygulamalar (sohbet, bildirimler, canlı güncellemeler) için daha uygundur. İki protokolü bir arada kullanmak, uygulamanızın her iki dünyanın da en iyi özelliklerinden faydalanmasını sağlar.
Aynı portta çalışmak performansı etkiler mi?
Genellikle hayır. Modern web sunucuları ve framework'ler, aynı port üzerinde HTTP ve WebSocket trafiğini verimli bir şekilde yönetmek üzere tasarlanmıştır. Ters proxy'ler (Nginx gibi) de bu trafiği sorunsuz bir şekilde yönlendirebilir. Performans sorunları genellikle uygulamanın kendi iç mantığından, veritabanı erişiminden veya yetersiz sunucu kaynaklarından kaynaklanır, protokollerin aynı portta çalışmasından değil.
Hangi teknolojiyi seçmeliyim (Node.js, Python, Go vb.)?
Seçiminiz, projenizin gereksinimlerine, ekibinizin uzmanlığına ve performans beklentilerinize bağlıdır. Node.js (Express ve Socket.IO ile), asenkron yapısı sayesinde hem REST hem de WebSockets için oldukça popüler ve etkilidir. Python (Flask/Django ve Flask-SocketIO/Django Channels ile) veya Go (Gorilla WebSocket gibi kütüphanelerle) da bu tür uygulamalar için güçlü alternatiflerdir. Önemli olan, seçtiğiniz teknolojinin gerçek zamanlı iletişim ve HTTP isteklerini aynı anda işleyebilme yeteneğidir.
Güvenlik için nelere dikkat etmeliyim?
Mutlaka SSL/TLS (HTTPS/WSS) kullanın. Hem REST hem de WebSocket bağlantıları için güçlü kimlik doğrulama ve yetkilendirme mekanizmaları uygulayın. Gelen verileri her zaman doğrulayın ve sanitasyon yapın. Rate limiting ve DoS koruması gibi önlemlerle sunucunuzu kötü niyetli saldırılardan koruyun. Güvenlik başlıklarını (Content Security Policy, X-Frame-Options vb.) doğru yapılandırın.