OpenAPI Callback'leri¶
🌐 Yapay Zekâ ve İnsanlar Tarafından Çeviri
Bu çeviri, insanlar tarafından yönlendirilen bir yapay zekâ ile oluşturuldu. 🤝
Orijinal anlamın yanlış anlaşılması ya da kulağa doğal gelmeme gibi hatalar içerebilir. 🤖
Yapay zekâ LLM'ini daha iyi yönlendirmemize yardımcı olarak bu çeviriyi iyileştirebilirsiniz.
Başka biri tarafından (muhtemelen API'nizikullanacak olan aynı geliştirici tarafından) oluşturulmuş birexternal API'ye request tetikleyebilen birpath operation ile bir API oluşturabilirsiniz.
API uygulamanızınexternal API'yi çağırdığı sırada gerçekleşen sürece "callback" denir. Çünkü dış geliştiricinin yazdığı yazılım API'nize bir request gönderir ve ardından API'nizgeri çağrı yaparak (call back), birexternal API'ye request gönderir (muhtemelen aynı geliştiricinin oluşturduğu).
Bu durumda, o external API'nin nasıl görünmesigerektiğini dokümante etmek isteyebilirsiniz. Hangipath operation'a sahip olmalı, hangi body'yi beklemeli, hangi response'u döndürmeli, vb.
Callback'leri olan bir uygulama¶
Bunların hepsine bir örnekle bakalım.
Fatura oluşturmayı sağlayan bir uygulama geliştirdiğinizi düşünün.
Bu faturalarınid,title (opsiyonel),customer vetotal alanları olacak.
API'nizin kullanıcısı (external bir geliştirici) API'nizde bir POST request ile fatura oluşturacak.
Sonra API'niz (varsayalım ki):
- Faturayı external geliştiricinin bir müşterisine gönderir.
- Parayı tahsil eder.
- API kullanıcısına (external geliştiriciye) tekrar bir bildirim gönderir.
- Bu, external geliştiricinin sağladığı birexternal API'ye (sizin API'nizden) bir POST request gönderilerek yapılır (işte bu "callback"tir).
NormalFastAPI uygulaması¶
Önce callback eklemeden önce normal API uygulamasının nasıl görüneceğine bakalım.
BirInvoice body alacak birpath operation'ı ve callback için URL'yi taşıyacakcallback_url adlı bir query parametresi olacak.
Bu kısım oldukça standart; kodun çoğu muhtemelen size zaten tanıdık gelecektir:
fromfastapiimportAPIRouter,FastAPIfrompydanticimportBaseModel,HttpUrlapp=FastAPI()classInvoice(BaseModel):id:strtitle:str|None=Nonecustomer:strtotal:floatclassInvoiceEvent(BaseModel):description:strpaid:boolclassInvoiceEventReceived(BaseModel):ok:boolinvoices_callback_router=APIRouter()@invoices_callback_router.post("{$callback_url}/invoices/{$request.body.id}",response_model=InvoiceEventReceived)definvoice_notification(body:InvoiceEvent):pass@app.post("/invoices/",callbacks=invoices_callback_router.routes)defcreate_invoice(invoice:Invoice,callback_url:HttpUrl|None=None):""" Create an invoice. This will (let's imagine) let the API user (some external developer) create an invoice. And this path operation will: * Send the invoice to the client. * Collect the money from the client. * Send a notification back to the API user (the external developer), as a callback. * At this point is that the API will somehow send a POST request to the external API with the notification of the invoice event (e.g. "payment successful"). """# Send the invoice, collect the money, send the notification (the callback)return{"msg":"Invoice received"}İpucu
callback_url query parametresi, Pydantic'inUrl tipini kullanır.
Tek yeni şey,path operation decorator'ına argüman olarak verilencallbacks=invoices_callback_router.routes. Bunun ne olduğuna şimdi bakacağız.
Callback'i dokümante etmek¶
Callback'in gerçek kodu, büyük ölçüde sizin API uygulamanıza bağlıdır.
Ve bir uygulamadan diğerine oldukça değişebilir.
Sadece bir-iki satır kod bile olabilir, örneğin:
callback_url="https://example.com/api/v1/invoices/events/"httpx.post(callback_url,json={"description":"Invoice paid","paid":True})Ancak callback'in belki de en önemli kısmı, API'nizin kullanıcısının (external geliştiricinin)external API'yi doğru şekilde uyguladığından emin olmaktır; çünküsizin API'niz callback'in request body'sinde belirli veriler gönderecektir, vb.
Dolayısıyla sıradaki adım olarak,sizin API'nizden callback almak için oexternal API'nin nasıl görünmesi gerektiğini dokümante eden kodu ekleyeceğiz.
Bu dokümantasyon, API'nizde/docs altındaki Swagger UI'da görünecek ve external geliştiricilereexternal API'yi nasıl inşa edeceklerini gösterecek.
Bu örnek callback'in kendisini implemente etmiyor (o zaten tek satır kod olabilir), sadece dokümantasyon kısmını ekliyor.
İpucu
Gerçek callback, sadece bir HTTP request'tir.
Callback'i kendiniz implemente ederkenHTTPX veyaRequests gibi bir şey kullanabilirsiniz.
Callback dokümantasyon kodunu yazın¶
Bu kod uygulamanızda çalıştırılmayacak; sadece oexternal API'nin nasıl görünmesi gerektiğinidokümante etmek için gerekiyor.
AncakFastAPI ile bir API için otomatik dokümantasyonu kolayca nasıl üreteceğinizi zaten biliyorsunuz.
O halde aynı bilgiyi kullanarak,external API'nin nasıl görünmesi gerektiğini dokümante edeceğiz... external API'nin implemente etmesi gerekenpath operation'ları oluşturarak (API'nizin çağıracağı olanlar).
İpucu
Bir callback'i dokümante eden kodu yazarken, kendiniziexternal geliştirici olarak hayal etmek faydalı olabilir. Ve şu andasizin API'nizi değil,external API'yi implemente ettiğinizi düşünün.
Bu bakış açısını (external geliştiricinin bakış açısını) geçici olarak benimsemek; parametreleri nereye koyacağınızı, body için Pydantic modelini, response için modelini vb. external API tarafında nasıl tasarlayacağınızı daha net hale getirebilir.
Bir callbackAPIRouter oluşturun¶
Önce bir veya daha fazla callback içerecek yeni birAPIRouter oluşturun.
fromfastapiimportAPIRouter,FastAPIfrompydanticimportBaseModel,HttpUrlapp=FastAPI()classInvoice(BaseModel):id:strtitle:str|None=Nonecustomer:strtotal:floatclassInvoiceEvent(BaseModel):description:strpaid:boolclassInvoiceEventReceived(BaseModel):ok:boolinvoices_callback_router=APIRouter()@invoices_callback_router.post("{$callback_url}/invoices/{$request.body.id}",response_model=InvoiceEventReceived)definvoice_notification(body:InvoiceEvent):pass@app.post("/invoices/",callbacks=invoices_callback_router.routes)defcreate_invoice(invoice:Invoice,callback_url:HttpUrl|None=None):""" Create an invoice. This will (let's imagine) let the API user (some external developer) create an invoice. And this path operation will: * Send the invoice to the client. * Collect the money from the client. * Send a notification back to the API user (the external developer), as a callback. * At this point is that the API will somehow send a POST request to the external API with the notification of the invoice event (e.g. "payment successful"). """# Send the invoice, collect the money, send the notification (the callback)return{"msg":"Invoice received"}Callbackpath operation'ını oluşturun¶
Callbackpath operation'ını oluşturmak için, yukarıda oluşturduğunuz aynıAPIRouter'ı kullanın.
Normal bir FastAPIpath operation'ı gibi görünmelidir:
- Muhtemelen alması gereken body'nin bir deklarasyonu olmalı, örn.
body: InvoiceEvent. - Ayrıca döndürmesi gereken response'un deklarasyonu da olabilir, örn.
response_model=InvoiceEventReceived.
fromfastapiimportAPIRouter,FastAPIfrompydanticimportBaseModel,HttpUrlapp=FastAPI()classInvoice(BaseModel):id:strtitle:str|None=Nonecustomer:strtotal:floatclassInvoiceEvent(BaseModel):description:strpaid:boolclassInvoiceEventReceived(BaseModel):ok:boolinvoices_callback_router=APIRouter()@invoices_callback_router.post("{$callback_url}/invoices/{$request.body.id}",response_model=InvoiceEventReceived)definvoice_notification(body:InvoiceEvent):pass@app.post("/invoices/",callbacks=invoices_callback_router.routes)defcreate_invoice(invoice:Invoice,callback_url:HttpUrl|None=None):""" Create an invoice. This will (let's imagine) let the API user (some external developer) create an invoice. And this path operation will: * Send the invoice to the client. * Collect the money from the client. * Send a notification back to the API user (the external developer), as a callback. * At this point is that the API will somehow send a POST request to the external API with the notification of the invoice event (e.g. "payment successful"). """# Send the invoice, collect the money, send the notification (the callback)return{"msg":"Invoice received"}Normal birpath operation'dan 2 temel farkı vardır:
- Gerçek bir koda ihtiyaç duymaz; çünkü uygulamanız bu kodu asla çağırmayacak. Bu yalnızcaexternal API'yi dokümante etmek için kullanılır. Yani fonksiyon sadece
passiçerebilir. - path, birOpenAPI 3 expression (aşağıda daha fazlası) içerebilir; böylece parametreler vesizin API'nize gönderilen orijinal request'in bazı parçalarıyla değişkenler kullanılabilir.
Callback path ifadesi¶
Callbackpath'i,sizin API'nize gönderilen orijinal request'in bazı parçalarını içerebilen birOpenAPI 3 expression barındırabilir.
Bu örnekte, bu birstr:
"{$callback_url}/invoices/{$request.body.id}"Yani API'nizin kullanıcısı (external geliştirici)sizin API'nize şu adrese bir request gönderirse:
https://yourapi.com/invoices/?callback_url=https://www.external.org/eventsve JSON body şu şekilde olursa:
{"id":"2expen51ve","customer":"Mr. Richie Rich","total":"9999"}o zamansizin API'niz faturayı işleyecek ve daha sonra bir noktadacallback_url'ye (yaniexternal API'ye) bir callback request gönderecek:
https://www.external.org/events/invoices/2expen51veve JSON body yaklaşık şöyle bir şey içerecek:
{"description":"Payment celebration","paid":true}ve oexternal API'den şu gibi bir JSON body içeren response bekleyecek:
{"ok":true}İpucu
Callback URL'sinin,callback_url içindeki query parametresi olarak alınan URL'yi (https://www.external.org/events) ve ayrıca JSON body'nin içindeki faturaid'sini (2expen51ve) birlikte kullandığına dikkat edin.
Callback router'ını ekleyin¶
Bu noktada, yukarıda oluşturduğunuz callback router'ında gerekli callbackpath operation'ları (external geliştiricininexternal API'de implemente etmesi gerekenler) hazır.
Şimdisizin API'nizin path operation decorator'ındacallbacks parametresini kullanarak, callback router'ının.routes attribute'unu (bu aslında route/path operation'lardan oluşan birlist) geçin:
fromfastapiimportAPIRouter,FastAPIfrompydanticimportBaseModel,HttpUrlapp=FastAPI()classInvoice(BaseModel):id:strtitle:str|None=Nonecustomer:strtotal:floatclassInvoiceEvent(BaseModel):description:strpaid:boolclassInvoiceEventReceived(BaseModel):ok:boolinvoices_callback_router=APIRouter()@invoices_callback_router.post("{$callback_url}/invoices/{$request.body.id}",response_model=InvoiceEventReceived)definvoice_notification(body:InvoiceEvent):pass@app.post("/invoices/",callbacks=invoices_callback_router.routes)defcreate_invoice(invoice:Invoice,callback_url:HttpUrl|None=None):""" Create an invoice. This will (let's imagine) let the API user (some external developer) create an invoice. And this path operation will: * Send the invoice to the client. * Collect the money from the client. * Send a notification back to the API user (the external developer), as a callback. * At this point is that the API will somehow send a POST request to the external API with the notification of the invoice event (e.g. "payment successful"). """# Send the invoice, collect the money, send the notification (the callback)return{"msg":"Invoice received"}İpucu
callback= içine router'ın kendisini (invoices_callback_router) değil,invoices_callback_router.routes şeklinde.routes attribute'unu verdiğinize dikkat edin.
Dokümanları kontrol edin¶
Artık uygulamanızı başlatıphttp://127.0.0.1:8000/docs adresine gidebilirsiniz.
Path operation'ınız için,external API'nin nasıl görünmesi gerektiğini gösteren bir "Callbacks" bölümünü içeren dokümanları göreceksiniz:








