İÇİNDEKİLER
- •SQL Server 2025'e geçişi ve yeni özellikleri birlikte planlayalım
- •Kısa Özet
- •sp_invoke_external_rest_endpoint Nedir?
- •1. Özelliği Etkinleştirme
- •2. Kullanıcı Yetkilendirmesi
- •3. Söz Dizimi ve Parametreler
- •4. GET ile Veri Çekme ve JSON Yanıtını İşleme
- •5. Gerçek Senaryo: TCMB Döviz Kurlarını Tabloya Yükleme
- •Agent job ile zamanlama
- •6. API Anahtarını Güvenli Saklama: DATABASE SCOPED CREDENTIAL
- •7. POST ile Dış Sisteme Veri Gönderme
- •8. Dönüş Kodları ve Hata Davranışları
- •Zaman aşımı ve yeniden deneme
- •9. Limitler
- •10. İzleme ve Performans
- •Ne Zaman Kullanmalı, Ne Zaman Kullanmamalı?
- •Production İçin Güvenlik Kontrol Listesi
- •Aryasoft ile SQL Server 2025
- •Sık Sorulan Sorular
- •Kaynaklar
- •SQL Server 2025 projenizi güvenle planlayın
SQL Server 2025 ile gelen sp_invoke_external_rest_endpoint, T-SQL içinden HTTPS üzerinden REST API çağırmanızı sağlar. Döviz kuru çekmek, bir webhook’a alarm göndermek ya da bir Azure servisine veri aktarmak artık PowerShell, SSIS veya ayrı bir uygulama gerektirmez. Özellik varsayılan olarak kapalıdır. Açmak için sunucu ayarı ve veritabanı yetkisi birlikte gerekir. Production (üretim ortamı) kullanımında ise yetki, kimlik bilgisi saklama ve hata yönetimi ilk günden planlanmalıdır.
Bu rehberde özelliği adım adım ele alıyoruz: etkinleştirme, yetkilendirme, GET ve POST örnekleri, kimlik bilgilerinin güvenli saklanması, hata davranışları ve izleme. Ekibimiz özelliği SQL Server 2025 üzerinde TCMB döviz kurları ve hava durumu verisiyle test etti. Yazıdaki tüm kodlar test sunucumuzda çalıştırıldı.
SQL Server 2025'e geçişi ve yeni özellikleri birlikte planlayalım
Aryasoft, SQL Server 2025 yükseltmesini, REST entegrasyonu gibi yeni özelliklerin güvenli kullanımını ve production'a geçişi uçtan uca yönetir.
Kısa Özet
| Konu | Özet |
|---|---|
| Ne işe yarar? | T-SQL içinden HTTPS REST endpoint çağırır; yanıtı JSON veya XML olarak döndürür. |
| Hangi platformlar? | SQL Server 2025 (17.x), Azure SQL Database, Azure SQL Managed Instance (SQL Server 2025 veya Always-up-to-date güncelleme politikası), Fabric SQL database |
| Varsayılan durum | SQL Server 2025 ve Managed Instance’ta kapalı; Azure SQL Database ve Fabric’te açık |
| Gerekli yetkiler | Açmak için ALTER SETTINGS (sunucu), çağırmak için EXECUTE ANY EXTERNAL ENDPOINT (veritabanı) |
| Protokol | Yalnızca HTTPS; HTTP adresleri reddedilir, yönlendirmeler takip edilmez. |
| Ne zaman uygun? | Basit, düşük hacimli, zamanlanmış entegrasyonlar: kur çekme, bildirim, Azure servislerine veri gönderme |
| Ne zaman uygun değil? | Yüksek hacimli, karmaşık iş kuralları içeren veya kullanıcı işlemini bekleten entegrasyonlar |
sp_invoke_external_rest_endpoint Nedir?
sys.sp_invoke_external_rest_endpoint, verilen adrese HTTPS isteği gönderen bir sistem saklı yordamıdır. İstek gövdesi (payload), HTTP başlıkları ve yöntem parametreyle verilir. Servisin yanıtı, HTTP durum kodu ve yanıt başlıklarıyla birlikte bir OUTPUT değişkenine döner.
Tipik kullanım alanları şunlardır:
- TCMB gibi kaynaklardan döviz kuru veya referans veri çekmek
- Başarısız Agent job’larını, disk doluluk alarmlarını bir webhook’a ya da olay yönetim sistemine göndermek
- Azure Functions, Event Hubs veya Logic Apps’e veri aktarmak
- Azure OpenAI gibi servislerden embedding üretmek
- Dış bir sistemin durumunu sorgulayıp sonucu tabloya yazmak
Azure SQL Database ve Managed Instance’ta yalnızca Microsoft’un izin listesindeki alan adları çağrılabilir: Azure Functions, Logic Apps, Event Hubs, Azure OpenAI, Microsoft Graph, Blob Storage gibi. Listede olmayan bir servis için Microsoft, API Management üzerinden yayınlamayı önerir. Bu liste SQL Server 2025’in kendi sunucularınızdaki kurulumu için geçerli değildir. Orada sınırı sunucunun ağ erişimi, DNS, proxy ve güvenlik duvarı kuralları belirler. Bizim test sunucumuz TCMB ve açık bir hava durumu servisine doğrudan erişebildi.
1. Özelliği Etkinleştirme
SQL Server 2025’te özellik kapalı gelir. ALTER SETTINGS yetkisi olan bir kullanıcı (sysadmin veya serveradmin) şu komutla açar:
EXEC sp_configure 'external rest endpoint enabled', 1;
RECONFIGURE WITH OVERRIDE;
SELECT name, value_in_use
FROM sys.configurations
WHERE name = N'external rest endpoint enabled';
value_in_use değeri 1 ise özellik açıktır. Bu ayar “advanced” seçenekler arasında değildir, bu yüzden önce show advanced options açmak gerekmez. Yeniden başlatma da gerekmez.
2. Kullanıcı Yetkilendirmesi
Sunucu ayarını açmak, herkesin API çağırabileceği anlamına gelmez. Çağrı yapacak kullanıcıya ilgili veritabanında EXECUTE ANY EXTERNAL ENDPOINT yetkisi verilmelidir. Yetkiyi tek tek kullanıcılara değil, bir role vermek yönetimi kolaylaştırır:
CREATE ROLE rest_caller;
GRANT EXECUTE ANY EXTERNAL ENDPOINT TO rest_caller;
ALTER ROLE rest_caller ADD MEMBER [ApiCallerUser];
Yetkisi olmayan bir kullanıcı denediğinde şu hatayı alır:
Bu yetki, verinin veritabanından dışarı çıkabileceği bir kanal açar. Uygulama kullanıcılarına toplu olarak vermeyin. Mümkünse yalnızca entegrasyon prosedürlerini çalıştıran ayrı bir kullanıcıya veya Agent job sahibine verin ve SQL Server Audit ile kimin ne zaman çağrı yaptığını kayıt altına alın.
3. Söz Dizimi ve Parametreler
| Parametre | Açıklama | Varsayılan |
|---|---|---|
@url |
Çağrılacak HTTPS adresi, nvarchar(4000) |
Zorunlu |
@method |
GET, POST, PUT, PATCH, DELETE, HEAD |
POST |
@payload |
Gönderilecek gövde: geçerli JSON, düzgün biçimli XML veya metin | Yok |
@headers |
Düz (iç içe olmayan) JSON biçiminde HTTP başlıkları | Yok |
@timeout |
Saniye cinsinden zaman aşımı, 1–230 | 30 |
@credential |
Kimlik bilgisini taşıyan DATABASE SCOPED CREDENTIAL adı | Yok |
@retry_count |
Geçici hatalarda yeniden deneme sayısı, 0–10 | 0 |
@response |
Yanıtın döneceği nvarchar(max) OUTPUT değişkeni |
Yok |
Varsayılan yöntemin POST olduğuna dikkat edin. Veri çekmek istiyorsanız @method = N'GET' değerini açıkça yazın. Yordam isteğe content-type: application/json ve accept: application/json başlıklarını kendisi ekler. XML dönen bir servis için Accept başlığını application/xml olarak değiştirmeniz gerekir.
4. GET ile Veri Çekme ve JSON Yanıtını İşleme
Aşağıdaki örnek, anahtar gerektirmeyen bir hava durumu servisinden İstanbul için üç günlük tahmini çeker. Yanıttaki diziler OPENJSON ile satırlara açılır ve sıra numarası ([key]) üzerinden birleştirilir:
DECLARE @ret int, @response nvarchar(max);
EXEC @ret = sys.sp_invoke_external_rest_endpoint
@url = N'https://api.open-meteo.com/v1/forecast?latitude=41.01&longitude=28.98&daily=temperature_2m_min,temperature_2m_max,precipitation_sum&forecast_days=3&timezone=Europe%2FIstanbul',
@method = N'GET',
@timeout = 30,
@response = @response OUTPUT;
IF @ret <> 0
THROW 50001, N'Hava durumu servisi çağrısı başarısız.', 1;
SELECT JSON_VALUE(@response, '$.response.status.http.code') AS http_status,
d.value AS tarih,
mn.value AS en_dusuk_c,
mx.value AS en_yuksek_c,
p.value AS yagis_mm
FROM OPENJSON(@response, '$.result.daily.time') AS d
JOIN OPENJSON(@response, '$.result.daily.temperature_2m_min') AS mn ON mn.[key] = d.[key]
JOIN OPENJSON(@response, '$.result.daily.temperature_2m_max') AS mx ON mx.[key] = d.[key]
JOIN OPENJSON(@response, '$.result.daily.precipitation_sum') AS p ON p.[key] = d.[key]
ORDER BY CAST(d.[key] AS int);
Yanıt iki bölümden oluşur. $.response HTTP durum kodunu ve yanıt başlıklarını taşır. Servisin döndürdüğü asıl veri ise $.result altındadır:
{
"response": {
"status": { "http": { "code": 200, "description": "OK" } },
"headers": { "Content-Type": "application/json; charset=utf-8", "...": "..." }
},
"result": {
"daily": {
"time": ["2026-11-06", "2026-11-07", "2026-11-08"],
"temperature_2m_min": [7.9, 6.9, 6.1],
"temperature_2m_max": [12.4, 11.4, 11.2]
}
}
}
5. Gerçek Senaryo: TCMB Döviz Kurlarını Tabloya Yükleme
ERP ve raporlama sistemlerinde günlük kur verisi en yaygın entegrasyon ihtiyaçlarından biridir. TCMB, kurları XML olarak yayınlar. Accept başlığı application/xml yapıldığında yordam yanıtı <output><response>…</response><result>…</result></output> biçiminde döndürür. TCMB’nin XML’i result düğümünün içinde yer alır.
Önce kurların yazılacağı tabloyu oluşturuyoruz:
CREATE TABLE dbo.ExchangeRate (
RateDate date NOT NULL,
CurrencyCode char(3) NOT NULL,
Unit int NOT NULL,
CurrencyName nvarchar(100) NOT NULL,
ForexBuying decimal(18,6) NULL,
ForexSelling decimal(18,6) NULL,
BanknoteBuying decimal(18,6) NULL,
BanknoteSelling decimal(18,6) NULL,
LoadedAt datetime2(0) NOT NULL CONSTRAINT DF_ExchangeRate_LoadedAt DEFAULT SYSDATETIME(),
CONSTRAINT PK_ExchangeRate PRIMARY KEY (RateDate, CurrencyCode)
);
Prosedür kurları çeker, XML’i ayrıştırır ve MERGE ile yükler. Aynı gün birden fazla çalışırsa kayıtları çoğaltmaz, günceller:
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
GO
CREATE OR ALTER PROCEDURE dbo.usp_LoadExchangeRates
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
DECLARE @ret int, @response nvarchar(max), @xml xml;
EXEC @ret = sys.sp_invoke_external_rest_endpoint
@url = N'https://www.tcmb.gov.tr/kurlar/today.xml',
@method = N'GET',
@headers = N'{"Accept":"application/xml"}',
@timeout = 60,
@retry_count = 3,
@response = @response OUTPUT;
SET @xml = TRY_CAST(@response AS xml);
IF @ret <> 0 OR @xml IS NULL
THROW 50001, N'TCMB çağrısı başarısız veya yanıt geçerli bir XML değil.', 1;
WITH src AS (
SELECT CONVERT(date, t.n.value('@Date', 'char(10)'), 101) AS RateDate,
c.n.value('@Kod', 'char(3)') AS CurrencyCode,
c.n.value('(Unit/text())[1]', 'int') AS Unit,
TRIM(c.n.value('(CurrencyName/text())[1]', 'nvarchar(100)')) AS CurrencyName,
TRY_CONVERT(decimal(18,6), c.n.value('(ForexBuying/text())[1]', 'varchar(20)')) AS ForexBuying,
TRY_CONVERT(decimal(18,6), c.n.value('(ForexSelling/text())[1]', 'varchar(20)')) AS ForexSelling,
TRY_CONVERT(decimal(18,6), c.n.value('(BanknoteBuying/text())[1]', 'varchar(20)')) AS BanknoteBuying,
TRY_CONVERT(decimal(18,6), c.n.value('(BanknoteSelling/text())[1]', 'varchar(20)')) AS BanknoteSelling
FROM @xml.nodes('/output/result/Tarih_Date') AS t(n)
CROSS APPLY t.n.nodes('Currency') AS c(n)
)
MERGE dbo.ExchangeRate AS tgt
USING src ON tgt.RateDate = src.RateDate AND tgt.CurrencyCode = src.CurrencyCode
WHEN MATCHED THEN
UPDATE SET Unit = src.Unit, CurrencyName = src.CurrencyName,
ForexBuying = src.ForexBuying, ForexSelling = src.ForexSelling,
BanknoteBuying = src.BanknoteBuying, BanknoteSelling = src.BanknoteSelling,
LoadedAt = SYSDATETIME()
WHEN NOT MATCHED THEN
INSERT (RateDate, CurrencyCode, Unit, CurrencyName, ForexBuying, ForexSelling, BanknoteBuying, BanknoteSelling)
VALUES (src.RateDate, src.CurrencyCode, src.Unit, src.CurrencyName,
src.ForexBuying, src.ForexSelling, src.BanknoteBuying, src.BanknoteSelling);
END;
GO
EXEC dbo.usp_LoadExchangeRates;
Test sunucumuzda prosedür 22 para birimini yükledi. İkinci çalıştırmada kayıt sayısı değişmedi. Birkaç ayrıntı önemli:
- Tarih, XML’deki
Dateözniteliğinden (AA/GG/YYYY) alınır. Hafta sonu ve tatillerdetoday.xmlson iş gününün bültenini döndürür. Birincil anahtar sayesinde aynı bülten iki kez yazılmaz. - SDR (XDR) gibi bazı kalemlerde efektif alış ve satış değeri yoktur. Bu yüzden değerler
TRY_CONVERTile alınır ve sütunlar NULL kabul eder. - Bazı para birimi adları sonda boşluk içerir;
TRIMbunu temizler.
Uyarı
Prosedürü QUOTED_IDENTIFIER OFF ile oluşturursanız XML metotları (nodes(), value()) çalışma anında Msg 1934 hatası verir. SSMS bu ayarı varsayılan olarak açar, ancak sqlcmd kapalı başlar. Biz de testte bu hatayı sqlcmd ile aldık. Scripti hangi araçla dağıtırsanız dağıtın, prosedürün başına SET QUOTED_IDENTIFIER ON yazın. Ayrıntılar için yanlış SET seçenekleriyle oluşturulan nesneler yazımıza bakabilirsiniz.
Agent job ile zamanlama
TCMB kurları iş günlerinde 15:30’da yayınlar. Test çağrımızda dönen Last-Modified başlığı da bunu gösterdi. Aşağıdaki job, prosedürü hafta içi her gün 15:45’te çalıştırır ve geçici bir hatada adımı iki kez daha dener:
USE msdb;
GO
EXEC dbo.sp_add_job @job_name = N'Load CBRT Exchange Rates', @owner_login_name = N'sa';
EXEC dbo.sp_add_jobstep @job_name = N'Load CBRT Exchange Rates', @step_name = N'Load rates',
@subsystem = N'TSQL', @database_name = N'YourDatabase',
@command = N'EXEC dbo.usp_LoadExchangeRates;',
@retry_attempts = 2, @retry_interval = 10;
EXEC dbo.sp_add_jobschedule @job_name = N'Load CBRT Exchange Rates', @name = N'Weekdays 15:45',
@freq_type = 8, @freq_interval = 62, @freq_recurrence_factor = 1,
@active_start_time = 154500;
EXEC dbo.sp_add_jobserver @job_name = N'Load CBRT Exchange Rates';
@freq_interval = 62, pazartesiden cumaya kadar olan günlerin bit toplamıdır (2+4+8+16+32). Job sahibi, bildirim ve geçmiş ayarları için SQL Server Agent rehberimize bakabilirsiniz.
6. API Anahtarını Güvenli Saklama: DATABASE SCOPED CREDENTIAL
API anahtarını veya token’ı @headers içine açık metin olarak yazmak, onu prosedür tanımında, plan önbelleğinde ve kaynak kontrolünde görünür hale getirir. Doğru yöntem, anahtarı şifreli saklanan bir DATABASE SCOPED CREDENTIAL içine koymaktır. Credential oluşturmak için veritabanında bir master key bulunmalıdır. Yoksa şu hatayı alırsınız:
-- Veritabanında master key yoksa bir kez oluşturulur
IF NOT EXISTS (SELECT 1 FROM sys.symmetric_keys WHERE name = '##MS_DatabaseMasterKey##')
CREATE MASTER KEY ENCRYPTION BY PASSWORD = N'<güçlü bir parola>';
CREATE DATABASE SCOPED CREDENTIAL [https://alerts.example.com/api]
WITH IDENTITY = 'HTTPEndpointHeaders',
SECRET = '{"x-api-key":"<API_ANAHTARI>"}';
GRANT REFERENCES ON DATABASE SCOPED CREDENTIAL::[https://alerts.example.com/api] TO rest_caller;
Çağrıda yalnızca credential adı verilir. Yordam anahtarı isteğe kendisi ekler. Testimizde, gönderilen başlıkları geri yansıtan bir servis üzerinden x-api-key başlığının isteğe eklendiğini doğruladık.
IDENTITY dört değer alabilir:
| IDENTITY | Ne yapar? |
|---|---|
HTTPEndpointHeaders |
SECRET içindeki anahtar-değer çiftlerini HTTP başlığı olarak ekler (API anahtarı, Bearer token). |
HTTPEndpointQueryString |
Değerleri adresin query string kısmına ekler. |
Managed Identity |
Azure’daki yönetilen kimlik ile Microsoft Entra token’ı alır. SQL Server 2025’te ayrıca allow server scoped db credentials ayarının açılması gerekir. |
Shared Access Signature |
Azure Storage için SAS token ile erişim sağlar. |
Credential adı da kurallara uymalıdır: geçerli bir HTTPS adresi olmalı, query string içermemeli ve çağrılan adresle aynı protokol ve alan adını taşımalıdır. Ayrıca credential, çağrılan adresten daha genel bir yolu göstermelidir. https://alerts.example.com/api için oluşturulan credential https://alerts.example.com/api/sql-events çağrısında kullanılabilir. Tersi, yani daha özel bir yol için oluşturulmuş credential’ı daha genel bir adreste kullanmak hata verir:
7. POST ile Dış Sisteme Veri Gönderme
DBA açısından en kullanışlı senaryolardan biri, alarm verisini bir webhook’a veya olay yönetim sistemine göndermektir. Aşağıdaki örnek, son 24 saatte başarısız olan Agent job’larını tek bir JSON belgesinde toplar ve credential kullanarak gönderir:
DECLARE @payload nvarchar(max) = (
SELECT @@SERVERNAME AS server_name,
j.name AS job_name,
msdb.dbo.agent_datetime(h.run_date, h.run_time) AS run_at,
h.message
FROM msdb.dbo.sysjobhistory AS h
JOIN msdb.dbo.sysjobs AS j ON j.job_id = h.job_id
WHERE h.step_id = 0
AND h.run_status = 0
AND msdb.dbo.agent_datetime(h.run_date, h.run_time) >= DATEADD(hour, -24, GETDATE())
FOR JSON PATH, ROOT('failed_jobs')
);
IF @payload IS NULL
RETURN; -- başarısız job yok, çağrı yapılmaz
DECLARE @ret int, @response nvarchar(max);
EXEC @ret = sys.sp_invoke_external_rest_endpoint
@url = N'https://alerts.example.com/api/sql-events',
@method = N'POST',
@payload = @payload,
@credential = [https://alerts.example.com/api],
@timeout = 30,
@retry_count = 2,
@response = @response OUTPUT;
SELECT @ret AS return_code,
JSON_VALUE(@response, '$.response.status.http.code') AS http_status;
Satırları tek tek göndermek yerine FOR JSON ile tek bir belgede toplamak, her satır için ayrı HTTPS bağlantısı açma maliyetini ortadan kaldırır. Microsoft da toplu gönderimi önerir. Sonuç kümesi boşsa FOR JSON NULL döndürür, bu yüzden boş istek göndermemek için kontrol eklenmiştir.
Kritik
Bu yordamla gönderilen her veri kurumun dışına çıkar. Kişisel veri içeren tabloları dış servislere göndermeden önce KVKK açısından aktarımın hukuki dayanağını ve hedef servisin konumunu değerlendirin. Yalnızca gereken alanları gönderin; müşteri adı, T.C. kimlik numarası gibi alanları payload’a koymayın.
8. Dönüş Kodları ve Hata Davranışları
Yordamın dönüş değeri ile HTTP durum kodu aynı şey değildir. 2xx yanıtlarda dönüş değeri 0’dır. Diğer HTTP yanıtlarında dönüş değeri doğrudan HTTP durum kodudur. Servise hiç ulaşılamazsa yordam hata fırlatır. Davranışları test sunucumuzda tek tek denedik:
| Durum | Sonuç |
|---|---|
| 2xx yanıt | Dönüş değeri 0 |
| 404 Not Found | Dönüş değeri 404; hata fırlatılmaz, @response dolar. |
| 302 yönlendirme | Dönüş değeri 302; yönlendirme takip edilmez. |
http:// adres |
Msg 31610: Accessing the external endpoint is only allowed via HTTPS. |
| Çözülemeyen alan adı, bağlantı hatası | Msg 31608: failed to communicate with the external rest endpoint |
| Zaman aşımı | Msg 31629: The external rest endpoint execution exceeded the timeout value. |
| Yetki yok | Msg 8189 |
| Credential yolu uyuşmuyor | Msg 31630 |
| Master key yok (credential oluştururken) | Msg 15581 |
Bu yüzden production kodunda iki ayrı kontrol gerekir. Birincisi, dönüş değerinin 0 olup olmadığı. İkincisi, TRY...CATCH ile bağlantı ve zaman aşımı hataları:
DECLARE @ret int, @response nvarchar(max);
BEGIN TRY
EXEC @ret = sys.sp_invoke_external_rest_endpoint
@url = N'https://alerts.example.com/api/health',
@method = N'GET',
@timeout = 60,
@retry_count = 3,
@response = @response OUTPUT;
IF @ret <> 0
-- Servis yanıt verdi ama 2xx dışında bir kod döndü
PRINT CONCAT(N'HTTP hatası: ', @ret, N' ', LEFT(@response, 500));
END TRY
BEGIN CATCH
-- Servise hiç ulaşılamadı: DNS, TLS, zaman aşımı, yetki
PRINT CONCAT(N'Çağrı yapılamadı. Msg ', ERROR_NUMBER(), N': ', ERROR_MESSAGE());
END CATCH;
Gerçek bir entegrasyonda PRINT yerine sonucu bir log tablosuna yazmanızı ve job’u hata durumunda başarısız olacak şekilde THROW ile sonlandırmanızı öneririz. Böylece Agent bildirimleri devreye girer.
Zaman aşımı ve yeniden deneme
@retry_count verildiğinde yordam 408, 429, 500, 502, 503 ve 504 yanıtlarında isteği yeniden dener. Servis Retry-After başlığı gönderirse bekleme süresi bu başlığa göre belirlenir. Göndermezse bu kodlarda artan bekleme (exponential backoff) uygulanır, diğer durumlarda varsayılan bekleme 200 milisaniyedir. Önemli bir ayrıntı: yeniden deneme açıkken @timeout, her deneme için değil tüm çağrı için toplam süre olarak uygulanır. Üç deneme planlıyorsanız zaman aşımını buna göre artırın.
9. Limitler
| Konu | Limit |
|---|---|
| Payload (gönderilen ve alınan) | UTF-8 olarak 100 MB |
| URL uzunluğu (credential query string dahil) | 8 KB |
| Query string (credential dahil) | 4 KB |
| Toplam başlık boyutu (istek ve yanıt) | 8 KB |
| Zaman aşımı | 1–230 saniye, varsayılan 30 |
| Yeniden deneme | 0–10, varsayılan 0 |
| Eş zamanlı dış bağlantı | Worker thread sayısının %15’i, en fazla 175 |
10. İzleme ve Performans
Yordam, dış servisin yanıtını beklerken HTTP_EXTERNAL_CONNECTION bekleme tipini raporlar. Bu süre boyunca isteği çalıştıran oturum bir worker thread tutar. Yavaş bir API, çok sayıda paralel çağrıyla birleştiğinde worker havuzunu ve eş zamanlı bağlantı limitini zorlayabilir. Anlık ve birikimli durumu şu sorgularla izleyebilirsiniz:
-- Şu anda dış servis yanıtı bekleyen istekler
SELECT r.session_id, r.wait_type, r.wait_time AS wait_time_ms, t.text
FROM sys.dm_exec_requests AS r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS t
WHERE r.wait_type = N'HTTP_EXTERNAL_CONNECTION';
-- Servis başlangıcından bu yana birikimli bekleme
SELECT wait_type, waiting_tasks_count, wait_time_ms, max_wait_time_ms
FROM sys.dm_os_wait_stats
WHERE wait_type = N'HTTP_EXTERNAL_CONNECTION';
Bekleme istatistiklerini genel olarak nasıl yorumladığımızı wait stats analizi yazımızda anlattık.
İpucu
REST çağrısını kullanıcı işleminin içine, örneğin bir trigger’a veya sipariş kaydeden prosedüre koymayın. Dış servis yavaşladığında transaction açık kalır, kilitler uzar ve sorun veritabanına taşınır. Doğru yapı, değişiklikleri bir kuyruk tablosuna yazıp gönderimi ayrı bir Agent job ile yapmaktır.
Ne Zaman Kullanmalı, Ne Zaman Kullanmamalı?
| Uygun | Uygun değil |
|---|---|
| Günde birkaç kez çalışan kur, referans veri çekme işleri | Saniyede çok sayıda çağrı gerektiren yüksek hacimli entegrasyonlar |
| Alarm ve bildirim gönderimi | Karmaşık iş kuralları, dönüşümler ve çok adımlı akışlar |
| Azure Functions, Event Hubs, Azure OpenAI gibi servislere veri aktarımı | Kullanıcı işleminin dış servisi beklediği senkron akışlar |
| Ayrı bir uygulama sunucusu kurmanın gereksiz olduğu küçük otomasyonlar | Dış servis hatalarının veritabanı işlemlerini durdurmaması gereken kritik süreçler |
Bu özellik uygulama katmanının veya entegrasyon platformunun yerini almaz. Basit ve kontrollü entegrasyonlarda ara katman ihtiyacını ortadan kaldırarak bakım yükünü azaltır.
Production İçin Güvenlik Kontrol Listesi
- Özelliği yalnızca gerçekten kullanılacak sunucularda açın.
EXECUTE ANY EXTERNAL ENDPOINTyetkisini bir role verin, rolü yalnızca entegrasyon hesaplarına atayın.- API anahtarlarını DATABASE SCOPED CREDENTIAL içinde saklayın. Prosedür koduna ve
@headersiçine açık metin yazmayın. - Sunucunun dış ağ erişimini güvenlik duvarında yalnızca gereken alan adlarıyla sınırlayın.
- Dışarı gönderilen veriyi en aza indirin, kişisel veriyi KVKK açısından değerlendirin.
- Dış servisten gelen yanıtı doğrulamadan kritik tablolara yazmayın.
- Çağrıları audit ve log tablosuyla kayıt altına alın,
HTTP_EXTERNAL_CONNECTIONbeklemesini izleyin.
Sunucu düzeyindeki genel sıkılaştırma adımları için SQL Server güvenlik sıkılaştırma rehberimize bakabilirsiniz. Bu yordamın Azure OpenAI ile embedding üretmek için nasıl kullanıldığını Azure SQL’de vektör arama yazımızda ele aldık.
Aryasoft ile SQL Server 2025
SQL Server 2025’e geçiş, yeni özelliklerin güvenli kullanımıyla birlikte planlandığında gerçek değer üretir. Aryasoft, yükseltme planını, sp_invoke_external_rest_endpoint gibi yeni özelliklerin yetki ve ağ tasarımını ve production’a geçiş sonrası izlemeyi birlikte ele alır. Yükseltme tarafını SQL Server 2025 upgrade rehberimizde ayrıntılı anlattık.
Sık Sorulan Sorular
HTTPEndpointHeaders veya HTTPEndpointQueryString kimliğiyle saklayın. Credential için veritabanında master key gerekir. Çağıran kullanıcıya credential üzerinde REFERENCES yetkisi verilmelidir.Kaynaklar
Bu rehberdeki teknik bilgiler Kasım 2026’da aşağıdaki resmî dokümantasyonla doğrulandı. Kod örnekleri SQL Server 2025 (17.0.4055.5) test sunucumuzda çalıştırıldı.
- Microsoft Learn: sys.sp_invoke_external_rest_endpoint
- Microsoft Learn: CREATE DATABASE SCOPED CREDENTIAL
- Microsoft Learn: OPENJSON
- TCMB gösterge niteliğindeki döviz kurları (XML)
SQL Server Danışmanlığı
SQL Server 2025 projenizi güvenle planlayın
Aryasoft, yükseltmeden yeni özelliklerin güvenli kullanımına ve production izlemesine kadar SQL Server 2025 sürecinizi uçtan uca yönetir.