HTTP GET, POST, PUT ve DELETE metotları, bir web uygulamasında istemci ile sunucu arasındaki veri alışverişinin türünü belirleyen dört temel eylemdir; GET veri okumak, POST yeni bir kayıt oluşturmak, PUT mevcut bir kaydı güncellemek, DELETE ise bir kaydı silmek için kullanılır. Bu dört metot, bir REST API tasarımının omurgasını oluşturur ve hangi isteğin sunucuda ne tür bir işlem tetikleyeceğini net biçimde tanımlar. Bir öğrencinin API çağrısı yaparken karşılaştığı karmaşanın büyük kısmı, aslında bu dört metodun taşıdığı "niyeti" doğru okuyamamaktan kaynaklanır.
HTTP Protokolü ve İstemci-Sunucu İletişiminin Mantığı
HTTP (Hypertext Transfer Protocol), internet üzerinde iki taraf arasındaki iletişimi standartlaştıran bir protokoldür ve temelde çok basit bir döngü üzerine kuruludur: istemci bir istek (request) gönderir, sunucu bu isteği işler ve bir yanıt (response) döndürür. Tarayıcıdan bir sayfa açtığınızda, mobil uygulamadan bir profil güncellediğinizde ya da bir sunucuya veri gönderen bir betik çalıştırdığınızda arka planda hep aynı döngü işler. İstemci burada tarayıcı, mobil uygulama veya bir kod parçası olabilir; sunucu ise isteği karşılayıp veritabanıyla veya iş mantığıyla etkileşime giren taraftır.
Bu döngüde API (Application Programming Interface), istemci ile sunucunun birbirini anlaması için ortak bir dil, bir arayüz görevi görür. API, sunucunun hangi işlemleri hangi kurallarla sunduğunu tanımlar; istemci bu kurallara uyduğu sürece sunucunun iç yapısını bilmeye ihtiyaç duymaz. Örneğin bir e-ticaret sisteminde istemci, ürün listesini nasıl bir veritabanı sorgusuyla getirdiğini bilmeden sadece doğru endpoint'e doğru istek türünü göndererek veriye ulaşır. Bu soyutlama, modern yazılım mimarisinin temel taşlarından biridir ve temel programlama mantığını öğreten video eğitimler aşamasında öğrencilerin karşılaştığı ilk pratik kavramlardan biri hâline gelir.
İşte tam bu noktada HTTP metotları devreye girer. Her metot, sunucuya gönderilen isteğin amacını, yani "niyetini" belirtir. GET isteği "bana veri göster" derken, POST isteği "yeni bir kayıt oluştur" anlamı taşır; PUT "bu kaydı güncelle", DELETE ise "bu kaydı kaldır" mesajını iletir. Sunucu, gelen isteğin hangi metotla yapıldığına bakarak nasıl davranması gerektiğine karar verir. Bu net ayrım sayesinde aynı endpoint üzerinden farklı metotlarla tamamen farklı işlemler tetiklenebilir; bu da API tasarımını hem öngörülebilir hem de tutarlı kılar. Bir sonraki bölümde bu dört metodu tek tek, veri taşıma biçimleri ve tipik kullanım senaryolarıyla birlikte inceleyeceğiz.
GET, POST, PUT ve DELETE Metotları Tek Tek Ne Yapar?
Her HTTP metodu, sunucudan beklenen işlemi net biçimde tanımlar ve bu işlemlere göre veriyi farklı şekillerde taşır. Bir API tasarlarken ya da mevcut bir API'yi tüketirken bu farkları bilmek, doğru isteği doğru şekilde kurmanın ilk şartıdır.
- GET: Sunucudan veri okumak veya listelemek için kullanılır. GET isteğinde veri gövde (body) içinde taşınmaz; genellikle URL'ye eklenen query parametreleriyle çalışır. Örneğin bir kitap listesini filtrelemek için
/kitaplar?yazar=orhangibi bir adres kullanılabilir. GET isteklerinin sunucuda herhangi bir veri değişikliğine yol açmaması beklenir. - POST: Sunucuda yeni bir kaynak oluşturmak için kullanılır. Gönderilecek veri, isteğin gövdesinde (body) taşınır; genellikle JSON formatında bir nesne olarak iletilir. Bir kullanıcı kayıt formu doldurduğunda veya yeni bir sipariş oluşturulduğunda tipik olarak POST isteği devreye girer.
- PUT: Sunucuda zaten var olan bir kaynağı tamamen güncellemek için kullanılır. Veri yine gövde içinde gönderilir, ancak amaç yeni bir kayıt yaratmak değil, mevcut kaydın tüm alanlarını yeni değerlerle değiştirmektir. Örneğin bir kullanıcı profilinin tüm bilgilerinin yeniden gönderilerek güncellenmesi PUT ile yapılır.
- DELETE: Belirtilen bir kaynağı sunucudan kaldırmak için kullanılır. Genellikle gövdeye ihtiyaç duymaz; hangi kaynağın silineceği çoğunlukla endpoint üzerindeki bir kimlikle (id) belirtilir, örneğin
/kitaplar/12adresine gönderilen bir DELETE isteği 12 numaralı kitabı siler.
Bu dört metodun ortak noktası, aynı kaynak üzerinde çalışsalar bile sunucuya tamamen farklı bir talimat iletmeleridir. Bir API endpoint'i genellikle aynı adresi (örneğin /kitaplar) farklı metotlarla farklı işlemler için kullanır; bu yüzden endpoint'in kendisi kadar, isteğin hangi metotla gönderildiği de sonucu belirleyen kritik bir unsurdur.
İdempotentlik Nedir? PUT ve POST Karşılaştırması
İdempotentlik, bir isteğin aynı parametrelerle birden fazla kez gönderilmesinin, sunucudaki sonucu ilk gönderimden sonra değiştirmemesi anlamına gelir. Başka bir deyişle, idempotent bir isteği bir kez de gönderseniz on kez de gönderseniz, sunucudaki nihai durum aynı kalır. Bu kavram, özellikle ağ hatası nedeniyle bir isteğin tekrar gönderilmesi gerektiğinde hangi işlemlerin güvenle tekrarlanabileceğini anlamak açısından önemlidir.
GET, PUT ve DELETE metotları idempotent kabul edilir. Bir GET isteğini kaç kez tekrarlarsanız tekrarlayın, veriyi sadece okursunuz, hiçbir şeyi değiştirmezsiniz. Bir PUT isteğiyle bir kaydı belirli değerlere güncellediğinizde, aynı isteği tekrar gönderseniz bile kayıt yine aynı değerlere sahip olur; sonuç değişmez. Aynı şekilde bir DELETE isteğiyle bir kaydı sildiğinizde, isteği tekrar gönderseniz kayıt zaten silinmiş olduğu için sonuç değişmeden kalır (genellikle sunucu ikinci istekte "bulunamadı" yanıtı döner, ama sistemin durumu değişmez).
POST ise idempotent değildir. Aynı POST isteğini iki kez gönderirseniz, sunucu her seferinde yeni bir kayıt oluşturur; bu da iki kez tekrarlanan bir "yeni kitap ekle" isteğinin veritabanında aynı bilgilere sahip iki ayrı kitap kaydı olarak sonuçlanabileceği anlamına gelir. Bu fark, PUT ile POST arasındaki en temel ayrımdır: PUT "bu kayıt şu hâle gelsin" der ve tekrarında sonuç değişmezken, POST "yeni bir kayıt yarat" der ve her tekrarında sistemde yeni bir etki bırakır.
- GET — idempotent, veri değiştirmez, sınırsız tekrarlanabilir.
- PUT — idempotent, mevcut kaydı günceller, tekrar gönderilse sonuç aynı kalır.
- DELETE — idempotent, kaynağı kaldırır, tekrar gönderilse sistem durumu değişmez.
- POST — idempotent değildir, her tekrarında yeni bir kayıt oluşturma riski taşır.
HTTP Durum Kodları ve Metotlarla İlişkisi
Bir HTTP isteği gönderildiğinde sunucu, isteğin sonucunu her zaman bir durum kodu ile birlikte döner. Bu kod, isteğin başarılı olup olmadığını, hangi türde bir sorun yaşandığını ya da sunucu tarafında ne olduğunu anlamanın en hızlı yoludur. Durum kodları rastgele değildir; hangi metodun kullanıldığına ve senaryoya göre belirli kalıplar izler. Örneğin bir GET isteğinde beklenen başarı kodu ile bir POST isteğinde beklenen başarı kodu farklıdır, çünkü ikisi farklı işlemler gerçekleştirir.
Aşağıdaki tablo, API geliştirirken en sık karşılaşılan durum kodlarını ve bu kodların hangi metot ya da senaryoyla ilişkilendiğini özetler:
| Durum Kodu | Anlamı | Tipik Metot/Senaryo |
|---|---|---|
| 200 OK | İstek başarıyla işlendi | GET ile veri okuma, PUT ile güncelleme sonrası |
| 201 Created | Yeni kaynak oluşturuldu | POST ile yeni kayıt ekleme |
| 204 No Content | İşlem başarılı ama gövdede içerik yok | DELETE sonrası veya bazı PUT işlemleri |
| 400 Bad Request | İstek gövdesi veya parametreleri hatalı | Eksik/yanlış alanla POST veya PUT gönderimi |
| 404 Not Found | İstenen kaynak bulunamadı | Var olmayan ID ile GET, PUT veya DELETE |
| 500 Internal Server Error | Sunucu tarafında beklenmeyen hata | Sunucu kodunda çökme, herhangi bir metotta oluşabilir |
Bu tablodan çıkarılacak en önemli sonuç, durum kodunun tek başına yeterli olmadığıdır; kodu, isteği hangi metotla ve hangi verilerle gönderdiğinizle birlikte okumak gerekir. Bir POST isteğine 200 yerine 201 dönmesi genellikle daha doğru bir API tasarımına işaret ederken, bir GET isteğine 404 dönmesi kaynağın veritabanında bulunmadığını gösterir. Hata ayıklama yaparken önce durum koduna, ardından yanıt gövdesindeki hata mesajına bakmak sorunu hızlıca daraltmanın en pratik yoludur.
Request ve Response Yapısı: Header, Body, Endpoint Mantığı
Her HTTP isteği üç temel bileşenden oluşur: endpoint, header'lar ve body. Endpoint, isteğin hangi kaynağa yönlendirileceğini belirten URL'dir. Örneğin https://api.ornek.com/kitaplar tüm kitapları temsil eden bir endpoint iken, https://api.ornek.com/kitaplar/12 ID'si 12 olan tek bir kitabı işaret eder. Endpoint tasarımında genellikle kaynak isimleri çoğul ve küçük harfle yazılır, bu da API'nin okunabilirliğini artırır.
Header'lar, istekle birlikte gönderilen ek bilgilerdir ve isteğin nasıl işleneceğini sunucuya bildirir. En sık kullanılan header'lardan biri Content-Type'tır; bu header, gönderilen body'nin JSON, form-data ya da başka bir formatta olduğunu belirtir. Authorization header'ı ise kullanıcının kimliğini doğrulamak için token veya kimlik bilgisi taşır. Header'lar olmadan sunucu, gelen veriyi doğru şekilde yorumlayamayabilir veya isteği yetkisiz olarak reddedebilir.
Body, isteğin gövdesinde taşınan asıl veridir ve yalnızca belirli metotlarda anlamlıdır. POST ve PUT istekleri, yeni bir kaynak oluşturmak ya da mevcut bir kaynağı güncellemek için body içinde veri taşır; örneğin bir kitap kaydı için {"baslik": "...", "yazar": "..."} gibi bir JSON gövdesi gönderilir. Buna karşılık GET ve DELETE istekleri genellikle body taşımaz, çünkü bu metotlar yeni veri göndermek yerine mevcut bir kaynağı okumak veya kaldırmak için tasarlanmıştır; gerekli bilgi çoğunlukla endpoint içindeki ID ile sağlanır.
Sunucudan dönen response da benzer bir yapıya sahiptir: bir durum kodu ve genellikle bir body içerir. Durum kodu isteğin sonucunu özetlerken, body varsa isteğin sonucuna dair ayrıntılı veriyi taşır. Örneğin başarılı bir GET isteğinde response body'si istenen kaynağın JSON temsili olurken, 404 durumunda body genellikle kısa bir hata mesajı içerir. Bu iki parçayı birlikte okumak, API ile çalışırken hem "ne oldu" hem de "neden oldu" sorularının cevabını verir.
Örnek Senaryo: Kitap Kayıt Sistemiyle GET, POST, PUT, DELETE
Dört metodun mantığını somutlaştırmanın en kolay yolu, basit bir kitap kayıt sistemi üzerinden ilerlemektir. Bu senaryoda /kitaplar endpoint'i tüm kitap koleksiyonunu, /kitaplar/{id} ise belirli bir kitabı temsil eder. Aşağıdaki adımlar, aynı kaynağın dört farklı metotla nasıl yönetildiğini gösterir:
- GET ile kitapları listeleme: İstemci
/kitaplarendpoint'ine GET isteği gönderir, body taşımaz. Sunucu, veritabanındaki tüm kitapları JSON dizisi olarak response body'sinde döner ve başarılıysa 200 durum koduyla yanıt verir. - POST ile yeni kitap ekleme: İstemci yine
/kitaplarendpoint'ine, bu kez POST isteği gönderir ve body içinde yeni kitabın başlık, yazar gibi bilgilerini taşır. Sunucu bu bilgiyi veritabanına kaydeder, yeni oluşturulan kaydı bir ID ile birlikte döner ve 201 durum kodunu bildirir. - PUT ile mevcut kitabı güncelleme: İstemci, güncellenecek kitabın ID'sini içeren
/kitaplar/12endpoint'ine PUT isteği gönderir; body'de kitabın güncellenmiş tüm alanları yer alır. Sunucu mevcut kaydı bu verilerle değiştirir ve genellikle 200 durum koduyla güncellenmiş kaydı döner. - DELETE ile kitabı silme: İstemci
/kitaplar/12endpoint'ine DELETE isteği gönderir, body taşımaz. Sunucu ilgili kaydı veritabanından kaldırır ve genellikle 204 durum koduyla, gövdede ek içerik olmadan yanıt verir.
Bu dört adım incelendiğinde dikkat çeken nokta, aynı endpoint ailesinin farklı metotlarla tamamen farklı işlemler gerçekleştirebilmesidir. Endpoint yapısı sabit kalırken, isteğin metodu ve varsa body içeriği, sunucunun hangi işlemi yapacağını belirler. Bu tutarlı yapı, REST tabanlı API'lerin okunabilir ve tahmin edilebilir olmasının temel nedenidir.
Python requests Kütüphanesiyle GET ve POST İsteği Örneği
Kitap kayıt sistemini konuşma düzeyinde ele aldıktan sonra sırada bunu gerçek bir Python koduyla görmek var. Python'da HTTP istekleri göndermenin en yaygın yolu requests kütüphanesidir; bu kütüphane, GET ve POST gibi metotları birkaç satırlık fonksiyon çağrısına indirger. Örneğin kitap listesini çekmek istediğinizde şöyle bir yapı kurulur:
import requests
response = requests.get("https://ornekapi.com/kitaplar")
print(response.status_code)
print(response.json())
Bu kodda requests.get() fonksiyonu sunucuya bir GET isteği gönderir ve karşılığında bir response nesnesi döner. Bu nesnenin status_code özelliği isteğin nasıl sonuçlandığını, json() metodu ise sunucudan gelen gövdeyi (body) Python sözlüğüne çevirerek okumanızı sağlar. Yeni bir kitap eklemek istediğinizde ise POST metodu devreye girer:
import requests
yeni_kitap = {"baslik": "Suç ve Ceza", "yazar": "Dostoyevski"}
response = requests.post("https://ornekapi.com/kitaplar", json=yeni_kitap)
print(response.status_code)
print(response.json())
Burada json=yeni_kitap parametresi, Python sözlüğünü otomatik olarak JSON formatına çevirip istek gövdesine yerleştirir. Sunucu isteği başarıyla işlerse genellikle 201 durum kodu ve oluşturulan kaydın bilgisini geri döndürür; bir hata varsa status_code değeri bunu size hemen gösterir, böylece kodunuzda "istek başarılı mıydı" sorusunu tahmin etmeden yanıtlayabilirsiniz.
Bu tür alıştırmalar, Python öğreniminde sözdizimini ezberlemekten çok "bir sistemin parçaları nasıl konuşur" sorusuna cevap arayan bir aşamayı temsil eder. Değişkenler, fonksiyonlar ve veri yapılarıyla kurulan temel bilgi, HTTP isteklerini okuyup yorumlayabilmenin altyapısını oluşturur; bu nedenle birebir Python dersleri kapsamında da bu tür pratik senaryolara sıkça yer verilir. Kod satırlarını tek tek çalıştırıp response nesnesinin içeriğini incelemek, API mantığının kağıt üzerinde kalmayıp elle tutulur hale gelmesini sağlar.
Java'da HTTP İstekleri Nasıl Çalışır?
Java tarafında HTTP isteği göndermenin mantığı, Python'daki akışla aynı temel adımları izler ama daha nesne yönelimli bir üslupla ilerler. Öncelikle bir istemci nesnesi oluşturulur; bu nesne, sunucuyla bağlantı kurmaktan ve isteği iletmekten sorumludur. Ardından gönderilecek isteğin özellikleri — hedef adres, kullanılacak metot (GET, POST, PUT veya DELETE) ve varsa gövde içeriği — bir istek nesnesi üzerinde adım adım tanımlanır. Bu yaklaşım, HTTP kavramlarını soyut bir şekilde bırakmaz; her bileşeni ayrı ayrı ele almanızı zorunlu kılarak protokolün mantığını daha görünür hale getirir.
İstek gönderildikten sonra sunucudan dönen yanıt, yine bir nesne olarak ele alınır. Bu yanıt nesnesinin durum kodu, header bilgileri ve gövde içeriği ayrı ayrı okunabilir; Python'daki response.status_code ve response.json() ile eşdeğer bir mantık, Java'da yanıt nesnesinin ilgili metotları üzerinden çalışır. Java'nın standart kütüphanesinde yer alan HttpClient benzeri yapılar, geliştiriciye isteği oluşturma, gönderme ve yanıtı işleme adımlarını net biçimde ayırma imkânı tanır; bu da özellikle büyük ölçekli sistemlerde hata ayıklamayı ve kodun okunabilirliğini kolaylaştırır.
Burada dikkat edilmesi gereken nokta, Spring gibi framework'lerin bu süreci daha da soyutlayarak geliştiriciye hazır araçlar sunmasıdır; ancak bu araçların arkasında hâlâ aynı istek-yanıt mantığı çalışır. Bir geliştiricinin framework kullanmadan önce bu temel akışı kavraması, ileride karşılaşacağı hataları çözerken büyük fark yaratır. Java'nın tip güvenliği ve nesne yönelimli yapısı, HTTP metotlarını ve durum kodlarını ele alırken düşünme disiplinini zorunlu kılar; bu da dilin öğretim açısından sağlam bir temel olmasının nedenlerinden biridir. Bu mantığı sıfırdan, adım adım pratikle oturtmak isteyenler için birebir Java dersleri bu tür istemci-sunucu senaryolarını uygulamalı olarak ele alır.
Bu Konuyu Pratikle Pekiştirmek İçin Nasıl İlerlemeli?
HTTP metotlarını gerçekten öğrenmenin yolu, tanımları ezberlemekten değil küçük denemeler yapmaktan geçer. Python veya Java temelli ilerleyen bir öğrenci için önerilecek en doğal adım, ücretsiz olarak erişilebilen basit API'ler üzerinde GET isteğiyle veri çekmeyi denemek, ardından POST ile veri göndermeyi, PUT ile güncellemeyi ve DELETE ile silmeyi sırasıyla uygulamaktır. Her adımda dönen durum kodunu ve gövde içeriğini incelemek, teorik bilgiyi somut bir alışkanlığa dönüştürür.
- Basit bir kaynak (ör. kitap, kullanıcı, görev) üzerinde dört metodu da sırayla deneyin.
- Her istekten sonra durum kodunu not edin ve beklediğiniz sonuçla karşılaştırın.
- Hatalı bir istek göndererek 4xx ve 5xx kodlarının nasıl tetiklendiğini gözlemleyin.
- Aynı senaryoyu hem Python hem Java ile kurup iki dildeki yaklaşımı karşılaştırın.
Bu aşamada kendi bilgi seviyenizi net biçimde görmek, öğrenme sürecini büyük ölçüde hızlandırır; hangi konunun sağlam oturduğunu, hangisinin tekrar gerektirdiğini bilmeden ilerlemek zaman kaybına yol açar. Kısa bir öz değerlendirme yapmak, sonraki adımı belirsizlikten kurtarır. Eğer API mantığını, Python veya Java temelli yazılım öğreniminin hangi noktasında olduğunuzu netleştirmek istiyorsanız ücretsiz kariyer keşfi testi size mevcut seviyenizi ve ilerleyebileceğiniz yönü göstermek için pratik bir başlangıç noktası olabilir.
Sık Sorulan Sorular
GET ve POST arasındaki temel fark nedir?
GET, sunucudan veri okumak için kullanılır ve genellikle istek gövdesi taşımaz; POST ise sunucuda yeni bir kayıt oluşturmak amacıyla veri gönderir ve bu veri istek gövdesinde taşınır. GET tekrarlandığında sunucuda değişiklik yaratmaz, POST ise her çağrıldığında yeni bir kayıt oluşturabilir.
PUT ile PATCH aynı şey midir?
Hayır. PUT genellikle bir kaynağın tamamını yeni verilerle değiştirmek için kullanılırken, PATCH yalnızca kaynağın belirli alanlarında kısmi güncelleme yapmak amacıyla tasarlanmıştır. İkisi de güncelleme amaçlı olsa da kapsamları farklıdır.
Bir API isteği neden 404 hatası döner?
404 durum kodu, istek yapılan adreste veya kaynakta sunucunun bir eşleşme bulamadığı anlamına gelir. Bu genellikle yanlış yazılmış bir endpoint, silinmiş bir kayıt veya hatalı bir kimlik (ID) değeri gönderildiğinde ortaya çıkar.
DELETE isteği gönderildikten sonra veri geri getirilebilir mi?
Bu, tamamen sunucu tarafındaki uygulamanın tasarımına bağlıdır. Çoğu sistemde DELETE isteği veriyi kalıcı olarak kaldırır; ancak bazı uygulamalar veriyi fiziksel olarak silmek yerine "pasif" olarak işaretleyerek geri getirilebilir hale getirebilir. Bu davranış API'nin dokümantasyonunda belirtilir.
İdempotentlik neden önemlidir?
İdempotentlik, aynı isteğin birden çok kez gönderilmesinin sonucu değiştirmemesini garanti eder. Ağ kesintisi veya zaman aşımı gibi durumlarda bir isteğin yanlışlıkla tekrar gönderilmesi ihtimaline karşı, idempotent metotların güvenle tekrarlanabilmesi sistemin kararlılığını korur.
Python'da API isteği göndermek için hangi kütüphane kullanılır?
Python'da en yaygın tercih requests kütüphanesidir. GET, POST, PUT ve DELETE gibi tüm HTTP metotlarını basit fonksiyon çağrılarıyla göndermeyi ve gelen yanıtı kolayca okumayı mümkün kılar.
Java ile HTTP isteği göndermek Python'dan zor mudur?
Zor olmaktan çok daha yapılandırılmıştır. Java'da istek ve yanıt nesnelerinin ayrı ayrı tanımlanması biraz daha fazla kod satırı gerektirebilir, ancak bu yapı HTTP protokolünün bileşenlerini daha net görmenizi sağlar; bu da uzun vadede hata ayıklamayı kolaylaştırır.
HTTP metotlarını kavramak, sadece API çağrısı yapabilmekten çok daha fazlasını kazandırır; istemci-sunucu iletişiminin mantığını anlamak, hangi dilde yazarsanız yazın yazılım geliştirme sürecinizin temelini güçlendirir. Bu konuyu daha derinlemesine pekiştirmek isteyenler Berk Akademi blog sayfasındaki diğer teknik içeriklere göz atabilir.