· 2026

PubMed literatür takip servisi

PubMed'i kayıtlı aramalara göre izleyip yeni makaleleri günlük e-posta özeti olarak gönderen, kendi sunucusunda çalışan bir servis. Boot.dev backend müfredatının bitirme projesi olarak, gerçek bir ihtiyacı öğrenme zemini olarak kullanarak kuruldu.

Sorun — ve neden bu kadar büyük bir proje

İki ayrı motivasyonu var, ve ikisini de açıkça söylemek gerekiyor.

Birincisi gerçek bir ihtiyaç: acil serviste vakalar arasında ölü zamanlar oluyor, ve kendi pratiğime denk düşen literatürü — göğüs ağrısı risk sınıflaması, sepsis tanıma, renal kolik gibi sık gördüğüm konuları — PubMed’e elle girip arama yapmayı hatırlamak zorunda kalmadan, pasif olarak takip edebilmek istiyordum. PubMed’in kendi e-posta uyarıları yönetmesi zahmetli ve istediğim gibi filtrelemiyor; literatür tarama servisleri ise derleme yazan araştırmacılara göre tasarlanmış, vakalar arasında işine yarar bir şey arayan klinisyene göre değil.

İkincisi ise şu: bu, boot.dev backend geliştirici müfredatını bitirme projemdi. Yani projenin boyutu — Go ve Python ve RabbitMQ ve PostgreSQL ve Docker ve bir React arayüzü, üç ayrı servis, bir kuyruk — literatür takip probleminin gerektirdiği boyut değil. Kendine e-posta atan bir araç için kimse RabbitMQ’ya uzanmaz. O boyut, müfredatın gerektirdiği boyut. Bunu baştan belirtmem gerekiyor: proje, gerçek bir ihtiyacı, kasıtlı olarak gereğinden büyük bir şey inşa etmek için zemin olarak kullandı — çünkü amaç kısmen problem, kısmen pratikti.

Bu yüzden bu proje, portföydeki diğerlerinden farklı bir soruya cevap veriyor. Diğerleri “şu operasyonel problemi nasıl çözdün” sorusuyla muhatap olurken; bu projenin cevap verdiği soru: “tam, dağıtılmış, çok bileşenli bir backend sistemini güncel profesyonel standartlarda baştan sona kurabiliyor musun?”.

Ne yaptım

Kendi sunucusunda çalışan bir servis. Kullanıcı, PubMed’in standart arama söz dizimiyle takip etmek istediği aramaları tanımlıyor; sistem bu aramaları belirli aralıklarla PubMed’e karşı çalıştırıyor, yeni eşleşen makaleleri çekiyor, filtreliyor, ve her sabah o güne dair yeni makaleleri bir e-posta özeti hâlinde gönderiyor.

Her arama için filtreler tanımlanabiliyor: yayın tipi izin/engel listeleri (yorum, errata, geri çekilme bildirimlerini ayıklamak için), minimum özet uzunluğu (konferans bildirilerini, mektupları ayıklamak için), tarama aralığı. Bir arama çok gürültülüyse filtreleri sıkılaştırıp yeniden çalıştırılabiliyor; çok darsa arama dizgesi genişletilebiliyor.

Sistemin kendisi üç servisten oluşuyor: PubMed’i belirli aralıklarla yoklayan ve HTTP API’sini sunan bir Go servisi; makaleleri çekip ayrıştıran ve filtreleyen bir Python işçisi; günlük özeti hazırlayıp gönderen ayrı bir Python işçisi. Aralarında bir RabbitMQ kuyruğu, altında bir PostgreSQL veritabanı. Arayüz, Go ikilisinin içine gömülü bir React uygulaması.

Teknik olarak ilginç olan ne

Bir bitirme projesinin doğası gereği, teknik içeriğin çoğu “bunu ilk kez yaptım” kategorisinde — kimlik doğrulama, oturum yönetimi, mesaj kuyruğu, çok servisli mimari, CI, dağıtım. Hepsini tek tek anlatmak bir özgeçmiş listesi olurdu. Onun yerine, gerçekten ilginç bulduğum birkaç karar:

Servislerin kuyrukla ayrılması. Üç servis doğrudan birbirini çağırmıyor; aralarında bir RabbitMQ kuyruğu var. Bu, başta gereksiz bir karmaşıklık gibi görünüyordu — ama PubMed’i yoklama döngüsü ile makaleyi çekme döngüsü gerçekten farklı hızlarda çalışıyor, ve farklı şekillerde başarısız olabiliyor. Kuyruk, ikisini birbirinden bağımsız kılıyor: çekme servisi yavaşlasa bile yoklama servisi etkilenmiyor, iş kuyrukta birikiyor ve sonra işleniyor.

Ağ çağrısından önce tekilleştirme. İşçi, bir makaleyi PubMed’den çekmeden önce o makalenin zaten veritabanında olup olmadığını kontrol ediyor. Bu, NCBI’ya karşı kibar olmak için: aynı makaleyi iki kez istememek, gereksiz ağ trafiği yaratmamak. Küçük bir detay ama dışarıdaki bir API’yi tükettiğinizde doğru olan davranış bu.

Özet işçisinin idempotentliği. Günlük e-posta özeti, aynı gün için iki kez gönderilmemeli — sunucu yeniden başlasa, zamanlayıcı iki kez tetiklense bile. Bu, veritabanında (kullanıcı, yerel_tarih) üzerine kısmi bir tekil indeks ile garanti altına alınıyor: aynı kullanıcı-gün çifti için ikinci bir özet kaydı oluşturulamıyor.

Dağıtım tarafında da küçük sürprizler vardı — örneğin Railway’in giden SMTP portunu engellemesi, e-postayı bir HTTPS API üzerinden göndermeyi gerektirdi.

Sonuç

Servis Railway üzerinde çalışıyor, ve kendi takip aramalarımı besliyor — şu an her sabah, bir önceki güne göre yeni çıkan, benim tanımladığım filtrelerden geçen makalelerin özetini alıyorum. Davetiyeyle birkaç kişi daha kullanıyor.

Ama bu projenin asıl çıktısı, servisin kendisi değil. Asıl çıktı şu: ayrı dosyalardan ibaret araçlardan, baştan sona dağıtılmış, test edilen, CI’dan geçen, bulutta çalışan çok bileşenli bir sisteme kadar olan mesafeyi bir kez baştan sona yürüdüm. Portföydeki diğer projeler belirli problemleri çözüyor; bu proje, o problemleri çözmek için gereken aracın kendisini — yani benim yapabildiklerimin sınırını — genişletmek için yapıldı.

Repo herkese açık ve MIT lisanslı. Çalışan örnek davetiyeyle; isteyen kendi örneğini Docker ile çalıştırabilir.