# Özel Request ve APIRoute sınıfı { #custom-request-and-apiroute-class } Bazı durumlarda, `Request` ve `APIRoute` sınıflarının kullandığı mantığı override etmek isteyebilirsiniz. Özellikle bu yaklaşım, bir middleware içindeki mantığa iyi bir alternatif olabilir. Örneğin, request body uygulamanız tarafından işlenmeden önce okumak veya üzerinde değişiklik yapmak istiyorsanız. /// danger | Uyarı Bu "ileri seviye" bir özelliktir. **FastAPI**'ye yeni başlıyorsanız bu bölümü atlamak isteyebilirsiniz. /// ## Kullanım senaryoları { #use-cases } Bazı kullanım senaryoları: * JSON olmayan request body'leri JSON'a dönüştürmek (örn. [`msgpack`](https://msgpack.org/index.html)). * gzip ile sıkıştırılmış request body'leri açmak (decompress). * Tüm request body'lerini otomatik olarak loglamak. ## Özel request body encoding'lerini ele alma { #handling-custom-request-body-encodings } Gzip request'lerini açmak için özel bir `Request` alt sınıfını nasıl kullanabileceğimize bakalım. Ayrıca, o özel request sınıfını kullanmak için bir `APIRoute` alt sınıfı da oluşturacağız. ### Özel bir `GzipRequest` sınıfı oluşturun { #create-a-custom-gziprequest-class } /// tip | İpucu Bu, nasıl çalıştığını göstermek için hazırlanmış basit bir örnektir; Gzip desteğine ihtiyacınız varsa sağlanan [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware) bileşenini kullanabilirsiniz. /// Önce, uygun bir header mevcut olduğunda body'yi açmak için `Request.body()` metodunu overwrite edecek bir `GzipRequest` sınıfı oluşturuyoruz. Header'da `gzip` yoksa body'yi açmayı denemez. Böylece aynı route sınıfı, gzip ile sıkıştırılmış veya sıkıştırılmamış request'leri handle edebilir. {* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[9:16] *} ### Özel bir `GzipRoute` sınıfı oluşturun { #create-a-custom-gziproute-class } Sonra, `GzipRequest`'i kullanacak `fastapi.routing.APIRoute` için özel bir alt sınıf oluşturuyoruz. Bu kez `APIRoute.get_route_handler()` metodunu overwrite edeceğiz. Bu metot bir fonksiyon döndürür. Bu fonksiyon da request'i alır ve response döndürür. Burada bu fonksiyonu, orijinal request'ten bir `GzipRequest` oluşturmak için kullanıyoruz. {* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[19:27] *} /// note | Teknik Detaylar Bir `Request`'in, request ile ilgili metadata'yı içeren bir Python `dict` olan `request.scope` attribute'u vardır. Bir `Request` ayrıca `request.receive` içerir; bu, request'in body'sini "almak" (receive etmek) için kullanılan bir fonksiyondur. `scope` `dict`'i ve `receive` fonksiyonu, ASGI spesifikasyonunun parçalarıdır. Ve bu iki şey, `scope` ve `receive`, yeni bir `Request` instance'ı oluşturmak için gerekenlerdir. `Request` hakkında daha fazla bilgi için [Starlette'ın Request dokümantasyonu](https://www.starlette.dev/requests/) bölümüne bakın. /// `GzipRequest.get_route_handler` tarafından döndürülen fonksiyonun farklı yaptığı tek şey, `Request`'i bir `GzipRequest`'e dönüştürmektir. Bunu yaptığımızda `GzipRequest`, veriyi (gerekliyse) *path operations*'larımıza geçirmeden önce açma (decompress) işini üstlenir. Bundan sonra tüm işleme mantığı aynıdır. Ancak `GzipRequest.body` içindeki değişikliklerimiz sayesinde, request body gerektiğinde **FastAPI** tarafından yüklendiğinde otomatik olarak decompress edilir. ## Bir exception handler içinde request body'ye erişme { #accessing-the-request-body-in-an-exception-handler } /// tip | İpucu Aynı problemi çözmek için, muhtemelen `RequestValidationError` için özel bir handler içinde `body` kullanmak çok daha kolaydır ([Hataları Ele Alma](../tutorial/handling-errors.md#use-the-requestvalidationerror-body)). Yine de bu örnek geçerlidir ve dahili bileşenlerle nasıl etkileşime geçileceğini gösterir. /// Aynı yaklaşımı bir exception handler içinde request body'ye erişmek için de kullanabiliriz. Tek yapmamız gereken, request'i bir `try`/`except` bloğu içinde handle etmek: {* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[14,16] *} Bir exception oluşursa, `Request` instance'ı hâlâ scope içinde olacağı için, hatayı handle ederken request body'yi okuyup kullanabiliriz: {* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[17:19] *} ## Bir router içinde özel `APIRoute` sınıfı { #custom-apiroute-class-in-a-router } Bir `APIRouter` için `route_class` parametresini de ayarlayabilirsiniz: {* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[26] *} Bu örnekte, `router` altındaki *path operations*'lar özel `TimedRoute` sınıfını kullanır ve response'u üretmek için geçen süreyi içeren ekstra bir `X-Response-Time` header'ı response'ta bulunur: {* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[13:20] *}