RFC 10008: Yeni HTTP QUERY Metodu
(rfc-editor.org)- RFC 10008, istek gövdesindeki sorguyu hedef kaynağın güvenli ve idempotent biçimde işlemesi ve ardından sonucu döndürmesi için HTTP QUERY metodunu tanımlar
- QUERY, GET'in safe/idempotent niteliği ile POST'un gövde taşıma biçimini birleştirerek uzun URI'ler, URI kodlama maliyeti, loglara sızma ve sorgu kombinasyonu başına kaynaklaştırma yükünü azaltır
- Sunucu, QUERY isteğini ancak Content-Type ile gövde birbiriyle tutarlıysa işleyebilir; desteklenmeyen türler, gövde uyuşmazlığı ve işlenemeyen sorgular farklı 4xx yanıtlarıyla ayrıştırılabilir
- Başarılı yanıtta Content-Location sorgu sonucu kaynağını, Location ise aynı sorguyu yeniden çalıştırabilecek bir equivalent resource'u gösterebilir
- QUERY yanıtları önbelleğe alınabilir, ancak önbellek anahtarının gövde ve metadata'yı da içermesi gerekir; CORS ortamında safelisted method olmadığından preflight gerekir
QUERY'nin çözmeye çalıştığı HTTP sorgu deseni
- RFC 10008, HTTP QUERY istek metodunu tanımlayan bir Internet Standards Track belgesidir
- QUERY, hedef kaynağın istek gövdesini işlemesini ve sonucunu yanıt olarak döndürmesini ister
- POST gibi gövde kullanır, ancak safe ve idempotent olarak tanımlandığı için otomatik yeniden deneme veya yeniden başlatma mümkündür
- Mevcut GET sorgularında girdiyi URI'ye koymak yaygındır
GET /feed?q=foo&limit=10&sort=-published HTTP/1.1
- Sorgu verisini URI'ye koymak, veri büyüdükçe daha fazla kısıt yaratır
- Birden fazla bağımsız sistemden geçtiği için gerçek URI boyutu sınırını önceden bilmek zordur
- HTTP, gönderici ve alıcının en az 8000 octets desteklemesini önerir, ancak yol üzerindeki tüm sistemler için garanti vermez
- Bazı verileri geçerli bir URI olarak kodlamanın maliyeti yüksektir
- İstek URI'sinin, istek gövdesine göre loglara düşme veya yer imlerine eklenme olasılığı daha yüksektir
- Sorgunun doğrudan URI'ye kodlanması, olası her girdi kombinasyonunun ayrı bir kaynak sayılması anlamına gelir
GET ile POST arasındaki anlamı netleştiren bir metot
- Birçok uygulama, sorguyu GET yerine POST gövdesiyle iletir
POST /feedContent-Type: application/x-www-form-urlencoded- gövde:
q=foo&limit=10&sort=-published
- Bu yaklaşımın güvenli ve idempotent bir sorgu olup olmadığı, belirli kaynak ve sunucu bilgisi olmadan anlaşılmaz
- QUERY ise aynı girdiyi istek gövdesiyle gönderirken, metodun kendisini güvenli ve idempotent olarak tanımlar
QUERY /feedContent-Type: application/x-www-form-urlencoded- gövde:
q=foo&limit=10&sort=-published
- Bu açık anlam sayesinde önbellekleme ve otomatik yeniden deneme gibi HTTP özelliklerini uygulamak kolaylaşır
- Sunucu, sorgunun kendisine veya belirli bir sorgu sonucuna URI atayarak bunun daha sonra GET isteklerinde kullanılmasını sağlayabilir
QUERY metodunun temel kuralları
- QUERY, sunucu tarafı bir sorgu başlatmak için kullanılır
- GET, hedef URI'nin tanımladığı kaynağın temsilini isterken QUERY, hedef kaynağın kapsamı içinde bir sorgu işlemi yürütülmesini ister
- İstek gövdesi ve medya tipi sorguyu tanımlar; origin server ise işlem kapsamını hedef kaynağa göre belirler
- Sunucu, Content-Type istek alanı yoksa veya istek gövdesiyle eşleşmiyorsa isteği başarısız saymalıdır
- Hedef URI'nin query part'ı, diğer tüm HTTP metotlarında olduğu gibi sorgu hedefi kaynağın tanımlanmasına katılır
- Bu query part'ın sonuca doğrudan etkisi olup olmadığı ve nasıl etki ettiği, kaynağa özgü davranıştır ve bu spesifikasyonun kapsamı dışındadır
- QUERY, hedef kaynak açısından güvenlidir
- İstemci, hedef kaynak durumunun değiştirilmesini istemez veya beklemez
- Sunucunun, ek bilgiye erişmek için HTTP kaynakları oluşturması yasak değildir
- QUERY idempotenttir; bu nedenle bağlantı hatasından sonra gerekirse yeniden denenebilir veya tekrar gönderilebilir
200 OKyanıtı, sorgunun başarıyla işlendiğini ve sonucun yanıt gövdesine dahil edildiğini gösterir
Medya tipi, uzlaşma ve hata işleme
- QUERY isteğinin anlamı, istek gövdesi ve medya tipi gibi ilgili metadata'ya göre değişir
- Gövde ile metadata'sı tutarsız istekler genellikle 4xx Client Error ile reddedilmelidir
- Hata işleme, isteğin nerede yanlış olduğuna göre değişir
- Medya tipi bilgisi yoksa istek tanım gereği hatalıdır; bu yüzden
400gibi bir 4xx durum koduyla başarısız olmalıdır - Medya tipi belirtilmiş ama kaynak bunu desteklemiyorsa
415 Unsupported Media Typeuygundur - Medya tipi ilke olarak bilinse bile hedef kaynağın QUERY anlamı yoksa bu da
415kapsamına girebilir - Medya tipi gerçek istek gövdesiyle uyuşmuyorsa
400 Bad Requestdöndürülebilir - Sunucu, gövdeye bakarak medya tipini tahmin edip eksik ya da yanlış değeri geçersiz kılan bir content sniffing yapamaz
- Tip ile gövde uyumlu olsa da gerçek sorgu içeriği nedeniyle işlenemiyorsa
422 Unprocessable Contentkullanılabilir - Sözdizimi olarak geçerli bir SQL sorgusunun var olmayan bir tabloyu hedeflemesi
422örneğidir - İstemcinin
Acceptile istediği yanıt medya tipini kaynak desteklemiyorsa406 Not Acceptableuygundur
- Medya tipi bilgisi yoksa istek tanım gereği hatalıdır; bu yüzden
Accept-Queryyanıt alanı, istemciye desteklenen sorgu medya tiplerini bildirebilir
equivalent resource, Content-Location, Location
- equivalent resource, belirli bir QUERY isteğini ve onun hedefini temsil eden, GET isteklerine yanıt veren kaynaktır
- equivalent resource hem istek gövdesini hem de metadata'yı dikkate alır
- Gövdenin medya tipi gibi representation metadata buna dahildir
- Sunucu equivalent resource için URI atayabilir, ancak bu zorunlu değildir
- Başarılı yanıt, Content-Location başlığıyla sorgu sonucuna karşılık gelen bir kaynak tanımlayıcısı içerebilir
- İstemci, belirtilen URI'ye GET göndererek az önce yürütülen sorgu işleminin sonucunu alabilir
- Bu kaynak geçici olabilir
- Başarılı yanıt, Location başlığıyla QUERY isteğinin equivalent resource URI'sini içerebilir
- İstemci, sorgu gövdesini yeniden göndermeden belirtilen URI'ye GET göndererek aynı sorgu işlemini tekrar edebilir
- Bu URI de geçici olabilir
- Sonraki istek başarısız olursa istemci, özgün QUERY hedefi ve daha önce gönderdiği gövdeyle yeniden deneyebilir
Yönlendirme ve koşullu istekler
- Sunucu, QUERY isteğine başka bir URI'ye kullanıcı aracısını yönlendiren dolaylı bir yanıt vermeyi seçebilir
301 Moved Permanentlyve308 Permanent Redirect, hedef kaynağın Location'ın işaret ettiği başka bir URI'ye kalıcı olarak taşındığını gösterir302 Foundve307 Temporary Redirect, hedef kaynağın geçici olarak taşındığı anlamına gelir- Dört durumda da sunucu, yeni hedef URI'ye benzer bir QUERY isteği gönderilerek özgün isteğin gerçekleştirilebileceğini önerir
301veya302sonrasında POST'u GET'e yönlendiren istisna, QUERY istekleri için geçerli değildir- QUERY için
303 See Other, özgün sorgunun Location'ın gösterdiği URI üzerindeki normal bir alma isteğiyle gerçekleştirilebileceğini belirtir- HTTP'de bu, yeni hedef URI'ye GET isteği gönderilmesi anlamına gelir
- Koşullu QUERY'de selected representation, ilgili QUERY isteğinin equivalent resource'una yapılan GET ile aynıdır
- İstemci, yalnızca koşullu başlıkların belirttiği şartlar sağlandığında sorgu sonucunun yanıt olarak döndürülmesini isteyebilir
Önbellekleme ve Range istekleri
- QUERY metodunun yanıtları önbelleğe alınabilir ve önbellek daha sonraki QUERY isteklerini karşılamak için kullanılabilir
- QUERY isteğinin önbellek anahtarı, istek gövdesini ve ilgili metadata'yı içermelidir
- Önbellek, önbellek anahtarı üretmek için anlamsal olarak önemli olmayan farkları kaldırabilir
- content encoding'in kaldırılması
+jsongibi medya subtype suffix'lerinin ifade ettiği biçim geleneğine göre normalizasyonContent-Type'ın ifade ettiği gövde anlamına göre normalizasyon
- Bu dönüşümler yalnızca önbellek anahtarı üretimi içindir; isteğin kendisini değiştirmez
- İstemci,
no-transformcache directive ile bu dönüşümleri istemediğini belirtebilir, ancak bu directive advisory niteliğindedir - QUERY yanıtlarının önbelleğe alınması GET'e göre doğası gereği daha karmaşıktır
- Önbellek anahtarını belirlemek için istek gövdesinin tamamını okumak gerekir
- QUERY yanıtı, equivalent resource URI'sini Location ile verirse istemci daha sonra GET'e geçerek işlemi basitleştirebilir
- QUERY'nin Range Request anlamı GET ile aynıdır
- Yazım sırasında tanımlı tek range unit olan Byte Range Request, QUERY sonuçları için çok az değer taşır
SQLiçindekiFETCH FIRST ... ROWS ONLYgibi, sorgu biçiminin kendisinin sonuç sınırlama veya sayfalama sağlaması yaygındır ve bu tür yerleşik özelliklerin kullanılması beklenir
Accept-Query yanıt başlığı
- Accept-Query yanıt başlığı, kaynağın QUERY metodunu desteklediğini doğrudan bildirir ve kullanılabilecek sorgu biçimi medya tiplerini tanımlar
- Accept-Query, Structured Fields sözdizimini kullanan bir media range listesidir
- media range, parametresiz media range değerini taşıyan Token veya String türünde bir List Structured Header Field olarak ifade edilir
- Medya tipi parametreleri, Structured Field Parameters'a eşlenir
- String ile Token seçimi anlamsal olarak önemli değildir
- Alıcı Token'ı String'e dönüştürebilir, ancak alınan türe göre farklı davranmamalıdır
- Medya tipleri Token'a bire bir eşlenmez; başta rakama izin verilen durumlarda String biçimi kullanılmalıdır
- Desteklenen wildcard'lar yalnızca
*/*veyaxxxx/*biçimindedir - Alan değerinde listelenen tiplerin sırası önemli değildir
- Accept-Query değeri, aynı path'i paylaşan bir sunucudaki tüm URI'lere uygulanır; query component dikkate alınmaz
- Aynı kaynak isteği farklı Accept-Query değerleri döndürürse, en son alınan fresh değer kullanılır
- Örnek şu şekildedir
Accept-Query: "application/jsonpath", application/sql;charset="UTF-8"
- Accept-Query,
Accepte benzese de Structured Field olduğu için RFC 9651'in Structured Fields işleme kurallarına uyulmalıdır
Güvenlik değerlendirmeleri ve CORS
- QUERY, RFC 9110'da tanımlanan tüm HTTP metotlarının genel güvenlik değerlendirmelerini izler
- QUERY, istek bilgisini URI query component'ine koyma yaklaşımına alternatif olarak kullanılabilir
- URI'ler, istek gövdelerine göre loglara düşme veya aracı sistemlerce işlenme olasılığı daha yüksek olduğundan, hassas bilgi içeren sorgularda GET yerine QUERY tercih edilmesi için bir gerekçe sunabilir
- Sunucu, QUERY sonucunu temsil eden geçici kaynaklar oluşturup bunlara URI atadığında, özgün istek gövdesinde loglara yazılmaması gereken hassas bilgiler varsa bu URI'lerde hassas kısımlara yer vermemelidir
- Önbellek, QUERY gövdesini yanlış normalize ederse veya kaynağın işleme biçiminden önemli ölçüde farklı normalize ederse false positive ile yanlış yanıt döndürebilir
- CORS uygulayan kullanıcı aracılarının QUERY isteklerinde preflight isteği gerekir
- QUERY, CORS-safelisted methods kümesinde yer almaz
IANA kaydı ve metot adının seçimi
- IANA, QUERY metodunu HTTP Method Registry'ye ekler
- Method Name:
QUERY - Safe:
yes - Idempotent:
yes - Specification: RFC 10008 Section 2
- Method Name:
- IANA, Accept-Query alanını HTTP Field Name Registry'ye ekler
- Field Name:
Accept-Query - Status:
permanent - Structured Type:
List
- Field Name:
- HTTP Method Registry'de zaten safe ve idempotent özelliklerine sahip
PROPFIND,REPORT,SEARCHbulunuyordu - Erken aşamada
SEARCHkullanıldı, ancak nihai metot adı QUERY oldu - QUERY'nin seçilme nedenleri şunlardır
- Alternatifler, istek gövdesinde genel medya tipi
application/xmlkullanıyor ve istek anlamı tamamen gövdeye bağlı oluyordu - Alternatiflerin tamamı WebDAV etkinliklerinden türemişti
QUERY, URI'nin query component'iyle ilişkisini iyi yakalar
- Alternatifler, istek gövdesinde genel medya tipi
1 yorum
Hacker News yorumları
Güçlü bir motivasyon örneği olsaydı daha ikna edici olurdu, ama GET ile fazla kolay ifade edilebilen bir örnek kullanıldığı için aksine dikkat dağıtıyor
Büyük JSON filtre yapıları ya da görsel girdisini istek gövdesine koyan bir QUERY hayal etseniz bile, istek gövdesinin önbellek anahtarının bir parçası olması çok tuhaf geliyor. Kullanıcının kontrol ettiği sonsuz önbellek anahtarları ortaya çıkıyor ve yaygın önbellekleme stratejileri pratikte istek gövdesini bit düzeyinde karşılaştırmak veya hash'lemekten ibaret olduğu için kötü niyetli durumlarda önbelleği geçersiz kılmak çok kolaylaşıyor
Karmaşık filtreleme ya da görsel gibi karmaşık girdiler gerektiren bir hizmet geliştiriyorsanız, önbellekleme muhtemelen HTTP katmanından oldukça uzakta olacaktır. Örneğin join'in tek tek veri sütunları ya da çözümlenmiş görsel girdisinin algısal hash'iyle anahtarlanan embedding'ler gibi, tel üzerindeki tam bit gösteriminden bağımsız olacaktır
Bunun neden illa genel amaçlı bir şekilde yakalanmak istendiğini anlamıyorum. Bunun yerine POST için
"Vary: request-body"gibi yeni bir başlıkla önbellekleme semantiğini ifade etmek çok daha iyi olurdu bence. Tam anlamıyla geriye dönük uyumlu olurdu ve bu davranışın işe yarayabileceği belki %0,1'lik CDN kullanım örnekleri dışında görmezden gelinebilirdiSorgu parametreleri için de aynen geçerli olmayan bir önbellekleme saldırısı aklıma gelmiyor. Önbelleği taşırmak istiyorsanız benzersiz 30 karakterlik sorgu parametreleri üretmek, 30 MB'lık istek gövdeleri üretmek kadar kolay
Gerçekte açık internete yönelik sistemler önbellek anahtarı olarak güvenli hash kullanıp bunu her zaman sabit boyutlu yapacaktır. Önbellek anahtarlarında zaten çok uzun olabilen URL'ler ve keyfi başlık değerleri kümeleri de var
Sorgu parametreli GET de zaten opaktır ve önbelleği geçersiz kılmayı kolaylaştırır
Ama QUERY'nin ardından POST kullanmak daha iyi olabilir gibi geliyor. Çünkü bu durumda sadece güvenli bayrağı eklenmiş aynı istek değil, iki farklı istek türü oluyorlar
HTML formlarının QUERY desteği ekleyip eklemeyeceğini merak ediyorum
QUERY idempotent olmak zorunda olduğundan, POST form gönderiminden çıkan sayfayı yenilerken görülen can sıkıcı yeniden gönderim uyarısını önleyebilir
method=QUERYeklenirse bu tuhaflığın bir yeni türü daha olacakHâlâ geçen yüzyıldaymış gibi yapmak isteyenler için: https://www.rfc-editor.org/rfc/rfc10008.txt
“GET isteğine gövde ekleme yaklaşımı IETF çalışma grubunda derinlemesine incelendi, ancak sonunda yeni QUERY metodunu oluşturma yönünde karar verildi. Ayrı bir metod oluşturma kararı, tarihsel birlikte çalışabilirlik sorunları ve HTTP'nin temel mimari tanımına sıkı bağlılık nedeniyle alındı”
Ama ben birkaç yıldır GET metoduyla istek gövdesi gönderiyorum
fetchhttps://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/U...
“GET istekleri gövde içeremez”
Şeffaf önbellekleme yüzünden tuhaf sorunlar da çıkabilir
Artık 5 haneli RFC numaralarına gelmiş olmamız şaşırtıcı
Biri RFC 10000'in ne zaman yayımlanacağı üzerine belirsiz bir bahis açmıştı ama numaralar 9998'den doğrudan 10008'e atladı. Kimse kazanamadı
https://manifold.markets/CollectedOverSpread/when-will-rfc-1...
HTTP sorgusunda arama sonuçlarını sorgulamak için QUERY metodu kullanılacak ve sorgu parametreleri eklenmeyecek gibi bir durum oluyor
İsim kafa karıştırıcı. Çünkü
queryterimi zaten genel olarak HTTP isteklerini ifade etmek için kullanılıyorSadece RFC başlığını görünce bile kafam karıştı
queryterimi HTTP isteklerini genel olarak hangi alanda ifade ediyor? Günlük dilde GET isteğine sorgu dendiği olur ama POST, PUT, DELETE için asla denmezDüzenleme: Aa, önbelleklenebilirlik için QUERY'yi yan etkisiz, yani “güvenli” bir metod olarak tanımlamışlar. Ben karıştırmışım
Bu gerçekten sorgu dizgili GET isteklerinin yerini sahada almaya başlarsa, tarayıcı yer imlerinin istek parametrelerini korumayı desteklemesini gerçekten isterim
Bunun RFC kapsamı dışında olduğunu biliyorum ama bunun kolay bir uzantısı sayesinde JS
EventSource'un akışlı yapay zeka sorgularında da çalışabilecek olması güzelİstekte gövde gerektiği için herkes POST kullanıyor ve akışlı sonuçlar için yanıtta sıkça
text/event-streamprotokolü kullanılıyor. Ama gerçekte durum değişmiyor, yani teknik olarak tam oturmuyor veEventSourceda inatla yalnızca GET kullanabiliyor. Bu yüzden birçok API aynı işlevi kendi ayrıştırıcısıyla baştan uyguluyorGET: Content (body) "no defined semantics"ifadesini görünce GET metodunda gövdeye izin vermenin sorun olmayabileceğini düşünmüştüm ama özgün spesifikasyonda GET gövdesi tamamen yok sayılmalıAyrıca isteğin önemli bir kısmı atılabilir bir gövdedeyse önbellekleme de bozulabilir
GET'e gövde parametreleri eklerseniz aynı URI'yi kullanan iki isteği artık aynı şeyi işaret ediyor sayamazsınız; bu da metodun kısıtını bozar