---
title: "Şemayı Kuyruğun Kenarında Doğrulamak"
description: "Bir mesajın data'sı, kuyruğun kontrol etmediği tipsiz bir sözleşmedir. Kenarda doğrula: üretici yayınlamadan önce, tüketici güvenlik ağı olarak."
url: https://sade.dev/tr/notes/semayi-kuyrugun-kenarinda-dogrulamak/
lang: tr
author: "Muhammet Şafak"
published: 2026-06-18
updated: 2026-09-06
section: Note
tags: ["queue","schema","reliability","architecture"]
summary: "Broker byte taşır, payload'ın içine asla bakmaz; tek bir servisin içindeki tip güvenliği veri telden geçtiği an buharlaşır. İki kenarda da doğrula, ama hangisinin kazandırdığını bil: üretici tarafı, yayınlamadan önce, hatayı senkron olarak gerçekten hatası olan serviste ortaya çıkarır. Tüketici tarafı ise kontrol etmediğin bir üreticiden gelen zehirli mesajı dead-letter kuyruğuna yönlendiren güvenlik ağıdır."
---

# Şemayı Kuyruğun Kenarında Doğrulamak

> Broker byte taşır, payload'ın içine asla bakmaz; tek bir servisin içindeki tip güvenliği veri telden geçtiği an buharlaşır. İki kenarda da doğrula, ama hangisinin kazandırdığını bil: üretici tarafı, yayınlamadan önce, hatayı senkron olarak gerçekten hatası olan serviste ortaya çıkarır. Tüketici tarafı ise kontrol etmediğin bir üreticiden gelen zehirli mesajı dead-letter kuyruğuna yönlendiren güvenlik ağıdır.

Bir worker production'da `KeyError` fırlatmaya başladı. Sebep kendi kodu değildi — upstream bir servis, olayın payload'ından bir alanı düşüren bir değişiklik shiplemişti ve kuyruk bozuk mesajı tek kelime etmeden taşımıştı. Hata, kötü mesaj değildi. Hata, onu sınırda kontrol eden hiçbir şeyin olmamasıydı.

## Kuyruk byte taşır, tip değil

Bir request body tipli bir handler'a çarpar; yanlış şekildeyse framework onu kapıda reddeder. Kuyruk sana bunun hiçbirini vermez. Payload opak JSON'dur — broker byte taşır ve içine asla bakmaz. Üretici ne koyduysa, tüketici onu alır, geçerli olsun olmasın. Tek bir servisin içinde sahip olduğun tip güvenliği, veri telden geçtiği an buharlaşır.

Yani bir mesajın şekli hakkında bir garanti istiyorsan, onu kendin eklemelisin — **kenarda**, verinin girdiği ve çıktığı yerde.

## Verinin girdiği ve çıktığı yerde doğrula

İki kenar var ve farklı hataları yakalar:

- **Üretici tarafında, yayınlamadan önce — birincil olan.** Payload'ı üretirken doğrula. Geçersiz veri kuyruğa hiç girmez, hata *senkron* olarak gerçekten hatası olan serviste ortaya çıkar ve bir kez yakalanır — mesaj her tüketiciye yayılmadan önce. Başarısız olmanın ucuz yeri burası.
- **Tüketici tarafında, alırken — güvenlik ağı.** Tüketirken yine doğrula. Bu, üretici tarafının yakalayamayacağını yakalar: kontrol etmediğin üreticilerden gelen mesajlar — başka bir takım, eski bir deploy edilmiş sürüm, elle hazırlanmış bir replay. Burada doğrulamayı geçemeyen mesaj zehirli bir mesajdır; handler'ı döngüde çökertmek yerine onu bir dead-letter kuyruğuna yönlendir.

Bilmeye değer bir incelik: çoğu kuyruk runtime'ında "anında reddet" kancası yoktur, yani tüketici tarafı bir ret genelde dead-letter'a gitmeden önce *retry* eder — ve geçersiz veri retry'de geçerli olmaz. Bu boşa iştir; üretici tarafının değerli olmasının sebebi tam olarak budur. Tüketici tarafı emniyet kemeridir, direksiyon değil.

## Şema envelope'la değil, mesajla yaşar

Doğruladığın şey, *mesaj türü başına* bir şemadır — olayın kimliğiyle anahtarlanır, taşıma envelope'una cıvatalanmaz. Onu bağımsız sürümlenen bir registry'de tut; [tüketicileri kırmadan dikkatle evrimleştirdiğin](/tr/journal/sema-evrimi-sozlesmeyi-kirmadan) aynı şema, runtime'da zorladığın şema olur. Tek sözleşme, hem değişim-anında (bu düzenleme birini kırıyor mu?) hem runtime'da (bu mesaj ona uyuyor mu?) kontrol edilir.

Bu, [bir mükerrer teslimatı no-op yapmanın](/tr/notes/idempotency-ayni-mesaj-iki-kez) yapısal kuzeni: ikisi de ne geldiğini kontrol etmediğini kabul eder ve garantiyi göndericiye güvenmek yerine kendi sınırına koyar.

## Ne zaman buna değmez?

Tek bir servisin iç kuyruğu — tek üretici, tek tüketici, birlikte deploy — buna ihtiyaç duymaz. Tip sistemi zaten iki ucu da kapsar; kenar doğrulaması törendir. *İkinci*, bağımsız deploy edilen bir üretici ya da tüketici var olduğu an değmeye başlar — farklı bir takım, farklı bir dil, farklı bir sürüm temposu. O an aynı zamanda tipsiz payload'ın sessizce en kırılgan sözleşmen hâline geldiği andır.

---

*İlgili:* [BabelQueue schema-validation spec'i](https://babelqueue.com/docs/spec/1.x/schema-validation) URN-başına şemayı ve nerede zorlandığını tanımlar; [babelqueue-registry](https://github.com/BabelQueue/babelqueue-registry) o şemaları tutar — kontrolü çalıştıran ise onun `bqschema` aracıdır.

## Sık sorulanlar

**Doğrulama üretici tarafında mı, tüketici tarafında mı yapılmalı?**

Birincil olan üretici tarafıdır: geçersiz veri kuyruğa hiç girmez, hata senkron olarak gerçekten hatası olan serviste ortaya çıkar ve mesaj her tüketiciye yayılmadan bir kez yakalanır. Tüketici tarafı, kontrol etmediğin üreticiler için güvenlik ağıdır: başka bir takım, eski bir deploy edilmiş sürüm, elle hazırlanmış bir replay.

**Tüketici tarafında doğrulamayı geçemeyen mesaj ne yapılmalı?**

Onu zehirli bir mesaj say ve handler'ı döngüde çökertmek yerine dead-letter kuyruğuna yönlendir. Geçersiz veri retry'de geçerli olmaz; tekrar denemek boşa iştir.


## Kaynaklar

- [JSON Schema Validation 2020-12](https://json-schema.org/draft/2020-12/json-schema-validation) — JSON Schema
- [Dead Letter Exchanges: when a message is dead-lettered](https://www.rabbitmq.com/docs/dlx) — RabbitMQ
