Temos um requisito comercial para poder solicitar um ponto de extremidade HTTP quando determinados eventos ocorrem no banco de dados (um banco de dados do SQL Server). Temos um catálogo de pontos finais que controlamos. Usamos SQL Server 2019 e 2022.
Atualmente, usamos o Service Broker External Activator , que funciona bem, mas essa tecnologia é antiga e, pelo que entendemos, não é mais suportada pela Microsoft. Além disso, a configuração/implementação é bastante complexa e a administração a marcou como "negócios inviáveis".
Quando trabalharmos no Azure, usaremos o novo sp_invoke_external_rest_endpoint para chamar uma função do Azure que fará a solicitação. Isso funciona bem e vamos usá-lo quando estiver no Azure.
Infelizmente, este procedimento NÃO está disponível na versão local padrão do SQL Server 2022. É por isso que planejamos usar EXECUTE sp_execute_external_script @language = N'Python'
para solicitar pontos de extremidade HTTP.
Já usamos o SQL Server Machine Learning Services em produção, então os temos disponíveis no SQL Server 2019 e 2022. Testamos essa implementação e parece estar funcionando bem, embora um pouco lento.
Queremos saber: Existe uma grande desvantagem em usar o Python para chamar endpoints HTTP que estão faltando em nossa avaliação?
Aqui está um exemplo do código que usamos para prova de conceito:
CREATE PROCEDURE [dbo].[usp_APICalls_HTTPRequest]
@URL NVARCHAR(100),
@Method VARCHAR(50),
@HeadersJSON NVARCHAR(MAX),
@BodyJSON NVARCHAR(MAX) = NULL,
@BodyParams NVARCHAR(MAX) = NULL,
@StatusCode VARCHAR(50) = NULL OUTPUT,
@ResponseBody NVARCHAR(MAX) = NULL OUTPUT
AS
EXECUTE sp_execute_external_script @language = N'Python',
@script = N'
import datetime
import json
import requests
print("")
print("Script started {:%Y-%m-%d %H:%M:%S}".format(datetime.datetime.now()))
print("")
objHeaders = json.loads(HeadersJSON)
if BodyJSON:
payload = json.dumps(json.loads(BodyJSON))
else:
payload = BodyParams
objReqResponse = requests.request(Method, URL, headers=objHeaders, data=payload)
objResponse = {
"StatusCode": [objReqResponse.status_code],
"Body": [objReqResponse.text]
}
StatusCode = str(objReqResponse.status_code)
ResponseBody = objReqResponse.text
print("")
print("Script complete {:%Y-%m-%d %H:%M:%S}".format(datetime.datetime.now()))
print("")
',
@params = N'@URL NVARCHAR(100),
@Method VARCHAR(50),
@HeadersJSON NVARCHAR(MAX),
@BodyJSON NVARCHAR(MAX),
@BodyParams NVARCHAR(MAX),
@StatusCode VARCHAR(50) OUTPUT,
@ResponseBody NVARCHAR(MAX) OUTPUT',
@URL = @URL,
@Method = @Method,
@HeadersJSON = @HeadersJSON,
@BodyJSON = @BodyJSON,
@BodyParams = @BodyParams,
@StatusCode = @StatusCode OUTPUT,
@ResponseBody = @ResponseBody OUTPUT
GO
Não há desvantagem em usar Python para fazer isso em vez de outra linguagem de extensão como SQL CLR.
Há uma desvantagem em fazer isso de forma síncrona em suas transações. Portanto, você provavelmente deve continuar usando o Service Broker e mudar da ativação externa para a ativação interna. Essa é a arquitetura usada pelo Database Mail para enviar solicitações SMTP, que têm os mesmos problemas que as solicitações HTTP.