Delphi'de Yeni HTTP QUERY Metodu | eSeGeCe Blog

Delphi'de Yeni HTTP QUERY Metodu

· Özellikler

IETF HTTP Çalışma Grubu, QUERY adında yeni bir HTTP istek metodu tanımladı (draft-ietf-httpbis-safe-method-w-body, RFC olma yolunda ilerliyor). QUERY, her REST geliştiricisinin karşılaştığı bir boşluğu dolduruyor: GET gibi güvenli ve idempotent bir istek, ancak POST gibi bir istek gövdesi taşıyor. sgcWebSockets artık QUERY'yi uçtan uca destekliyor: HTTP/1.1, HTTP/2 ve HTTP/3 istemcilerinde ve sunucu bileşenlerinde, Delphi ve C++ Builder için.

Neden yeni bir HTTP metodu?

Şimdiye kadar bir sunucuya sorgu göndermenin iki yolu vardı ve ikisinin de sorunları var. Sorguyu bir GET isteğinin URL'sine kodlayabilirsiniz, ancak URL'lerin pratik uzunluk sınırları vardır, karmaşık sorguları kaçış karakterleriyle yazmak zahmetlidir ve tam URL genellikle proxy ve sunucu günlüklerine düşer ki burası hassas filtre değerleri için kötü bir yerdir. Ya da sorguyu bir POST isteğinin gövdesinde gönderebilirsiniz, ancak POST güvenli değildir, idempotent değildir ve önbelleğe alınamaz: bir HTTP istemcisinin bağlantı hatasından sonra isteği otomatik olarak yeniden denemesine izin verilmez ve önbellekler yanıtı saklamaz.

QUERY her ikisinin de en iyi yanlarını birleştiriyor. İstek içeriği ve Content-Type başlığı sorguyu tanımlar, bu nedenle sorgu gerektiği kadar büyük ve yapılandırılmış olabilir (form verisi, JSON, SQL, JSONPath, sunucu neyi kabul ediyorsa). Aynı zamanda spesifikasyon QUERY'yi güvenli ve idempotent olarak tanımlar: kaynağın durumunu asla değiştirmez, güvenle yeniden denenebilir veya tekrarlanabilir ve yanıtları tıpkı bir GET yanıtı gibi önbelleğe alınabilir.

QUERY nasıl çalışır

Bir QUERY isteği, GET semantiğine sahip bir POST gibi görünür. Spesifikasyondan uyarlanan bu örnek, bir kişiler kaynağından filtrelenmiş bir projeksiyon istiyor:

QUERY /contacts HTTP/1.1
Host: example.org
Content-Type: application/x-www-form-urlencoded
Accept: application/json

select=surname,givenname,email&limit=10

HTTP/1.1 200 OK
Content-Type: application/json

[
  { "surname": "Smith", "givenname": "John", "email": "smith@example.org" },
  { "surname": "Jones", "givenname": "Sally", "email": "sally.jones@example.com" }
]

Spesifikasyondaki en önemli kurallar:

HTTP/1.1 istemcisinden QUERY

HTTP/1.1 istemcisi, Post karşılıkları gibi çalışan Query ve QueryAsync metotları kazanıyor: URL'yi ve sorgu gövdesini içeren bir akışı geçirin, istekte Content-Type değerini ayarlayın ve sonucu okuyun.

uses
  Classes, sgcHTTP;

var
  oClient: TsgcHTTP1Client;
  oQuery: TStringStream;
  vResult: string;
begin
  oClient := TsgcHTTP1Client.Create(nil);
  try
    oQuery := TStringStream.Create('select=surname,givenname,email&limit=10');
    try
      oClient.Request.ContentType := 'application/x-www-form-urlencoded';
      oClient.Request.Accept := 'application/json';
      vResult := oClient.Query('https://api.example.org/contacts', oQuery);
    finally
      oQuery.Free;
    end;
  finally
    oClient.Free;
  end;
end;

QUERY idempotent olduğundan, istemcinin yeniden deneme seçenekleriyle de iyi çalışır: bağlantı hatasıyla başarısız olan bir QUERY, sunucuda bir durum değişikliğini yineleme riski olmadan otomatik olarak yeniden denenebilir. Aynı Query metotları REST API temel istemcisinde de mevcuttur, bu sayede sgcWebSockets üzerine kurulu özel API entegrasyonları bu fiili ekstra bir çalışma olmadan benimseyebilir.

HTTP/2 ve HTTP/3 üzerinden QUERY

HTTP/2 ve HTTP/3 istemcileri aynı fiili sunar. HTTP/2 üzerinden istek, :method sözde başlığı QUERY olarak ayarlanmış şekilde ve gövde DATA çerçeveleri içinde gönderilir:

uses
  Classes, sgcHTTP;

var
  oClient: TsgcHTTP2Client;
  oQuery: TStringStream;
  vResult: string;
begin
  oClient := TsgcHTTP2Client.Create(nil);
  try
    oQuery := TStringStream.Create('select=surname,givenname,email&limit=10');
    try
      vResult := oClient.Query('https://api.example.org/contacts', oQuery);
    finally
      oQuery.Free;
    end;
  finally
    oClient.Free;
  end;
end;

HTTP/3 istemcisi, varsayılan olarak form-urlencoded içerik türünü kullanan bir string aşırı yüklemesi sunar; bu da basit sorguları tek bir çağrıda tutar:

uses
  sgcHTTP;

var
  oClient: TsgcHTTP3Client;
  vResult: string;
begin
  oClient := TsgcHTTP3Client.Create(nil);
  try
    vResult := oClient.Query('https://api.example.org/contacts',
      'select=surname,givenname,email&limit=10');
  finally
    oClient.Free;
  end;
end;

Sunucuda QUERY isteklerini işleme

Sunucu tarafında TsgcWebSocketHTTPServer, HTTP/1.1 ve HTTP/2 üzerinden QUERY isteklerini kabul eder ve bunları, istek gövdesi zaten okunmuş ve PostStream içinde hazır olacak şekilde OnCommandOther olayına yönlendirir. Minimal bir işleyici Content-Type başlığını doğrular, sorguyu çalıştırır ve sonucu döndürür:

procedure TForm1.ServerCommandOther(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  vQuery: string;
begin
  if SameText(ARequestInfo.Command, 'QUERY') then
  begin
    // the specification requires a Content-Type on every QUERY request
    if (ARequestInfo.ContentType = '') or
      not Assigned(ARequestInfo.PostStream) then
    begin
      AResponseInfo.ResponseNo := 400;
      Exit;
    end;

    ARequestInfo.PostStream.Position := 0;
    vQuery := ReadStringFromStream(ARequestInfo.PostStream);

    AResponseInfo.ResponseNo := 200;
    AResponseInfo.ContentType := 'application/json';
    AResponseInfo.ContentText := RunContactsQuery(vQuery);
  end;
end;

HTTP/3 sunucusu QUERY gövdelerini aynı şekilde okur, OpenAPI sunucusu bir OpenAPI spesifikasyonunda bildirilen query operasyonlarını yönlendirir ve metodu CORS varsayılanlarında duyurur, HTTP yönlendirme özelliği ise QUERY isteklerini gövdeleriyle birlikte bir arka uç sunucusuna iletir.

Kullanılabilirlik

QUERY desteği, sgcWebSockets 2026.7 içinde HTTP/1.1, HTTP/2 ve HTTP/3 istemcilerini, REST API temel istemcisini, sunucu bileşenlerini ve OpenAPI sunucusunu kapsayacak şekilde, Delphi 7'den Delphi 13'e kadar ve C++ Builder için yer alıyor. Alttaki aktarım biçimi düz HTTP olduğundan, metodu anlayan herhangi bir sunucu veya istemciyle bugün birlikte çalışabilir. En son sürümü sgcWebSockets indirme sayfasından indirebilirsiniz.

Sorularınız, geri bildiriminiz var mı veya geçiş konusunda yardım mı gerekiyor? Bize ulaşın, kodu yazan kişilerden yanıt alacaksınız.