MongoDB
Typed collection’ları DI’ye bağlayın ve database timeout’unu koruyan operation context kullanın.
lily_mongodb, varsayılan single modda Singleton DatabaseService kaydeder. Uygulama başlangıcında bağlanır ve readiness ping yapar. Ana erişim akışı controller → domain service → typed collection şeklindedir.
Bağımlılıklar ve bağlantı#
Çalışan MongoDB gerekir. İlk uygulamadaki lilyrs satırına mongodb feature’ını ekleyin; bu single modu seçer. Örnek aşağıdaki bağımlılıkları kullanır:
lilyrs = { version = "0.1.0", features = ["http-api", "mongodb"] }
tokio = { version = "1", features = ["macros", "rt-multi-thread", "time"] }serde derive bağımlılığı ilk uygulamadan gelir. MongoFilter, MongoRepositoryError ve operation context tipleri de lilyrs::mongodb üzerinden alınır; ayrı repository yardımcı crate’i gerekmez. BSON tipleri de aynı facade’den alınır. Mongo derive’ları gerekli yardımcı yolları kendileri çözer; bu örnekte ayrıca driver, async-trait veya futures bağımlılığı gerekmez.
[database]
mode = "single"
database_type = "mongodb"
connection_string = "mongodb://127.0.0.1:27017"
database_name = "lily"
query_timeout_secs = 10Typed collection ve domain service#
use std::sync::Arc;
use lilyrs::http_api::Injectable;
use lilyrs::http_api::{CancellationToken, ExecutionCancellation, ServiceTrait};
use lilyrs::mongodb::{Collection, DatabaseService, MongoCollection, Repository};
use lilyrs::mongodb::{MongoFilter, MongoRepositoryError};
use lilyrs::mongodb::bson::{doc, oid::ObjectId};
use serde::{Deserialize, Serialize};
#[derive(Clone, Serialize, Deserialize)]
struct User {
#[serde(skip_serializing_if = "Option::is_none")]
_id: Option<ObjectId>,
name: String,
}
#[derive(Default, Injectable, MongoCollection)]
#[service(lifetime = "Singleton")]
#[collection("users")]
#[collection_type(User)]
struct UserCollection {
#[inject]
db: Arc<DatabaseService>,
collection: Option<Collection<User>>,
}
// MongoCollection, ServiceTrait implementasyonunu kendisi üretir.
#[derive(Injectable)]
#[service(lifetime = "Singleton")]
struct UserService {
#[inject]
database: Arc<DatabaseService>,
#[inject]
users: Arc<UserCollection>,
}
impl ServiceTrait for UserService {}
impl UserService {
async fn find_by_name(&self, name: &str, stopping: ExecutionCancellation)
-> Result<Option<User>, MongoRepositoryError>
{
let token = CancellationToken::new();
let operation = self.database.operation_context(token.clone())?;
let filter = MongoFilter::new(doc! { "name": name })?;
let work = self.users.find_one(filter, &operation);
tokio::pin!(work);
tokio::select! {
biased;
_ = stopping.cancelled() => {
token.cancel();
work.await
}
result = &mut work => result,
}
}
}
// Ortak repository sözleşmesi tercih edilirse eklenir.
#[derive(Default, Injectable, Repository)]
#[service(lifetime = "Singleton")]
#[entity_type(User)]
#[collection_type(UserCollection)]
struct UserRepository {
#[inject]
collection: Arc<UserCollection>,
}
impl ServiceTrait for UserRepository {}Action’da Service<UserService> çözün ve request’in ExecutionCancellation değerini find_by_name çağrısına iletin. Entity’yi HTTP DTO’suna dönüştürün; storage tiplerini public API modeline doğrudan taşımak zorunda değilsiniz.
Derive sorumlulukları#
MongoCollection typed CRUD ile ServiceTrait implementation’ını birlikte üretir. İkinci bir ServiceTrait yazmayın. Opsiyonel Repository ortak repository sözleşmesini üretir; onun için Injectable ve ServiceTrait yine gerekir.
MongoFilter::new boş filtreyi reddeder. Bütün kayıtları hedeflemek için açık MongoFilter::all kullanın. Çoklu okumalar MongoPageRequest ile sınırlanır. Generated update tam entity replacement’tır; PATCH değildir. Optimistic concurrency için with_expected_revision seçilebilir.
Timeout ve cancellation#
DatabaseService::operation_context(token) configured query timeout’unu korur. MongoOperationContext::detached() ise deadline içermez. HTTP ana yolunda configured context ve örnekteki açık cancellation bağlantısını kullanın.
Factory modu#
Facade’de mongodb yerine mongodb-factory seçin: features = ["http-api", "mongodb-factory"]. Base mongodb feature’ı single modu açtığından aynı dependency graph içinde factory ile birleştirilemez. Collection Arc<MongoFactory> inject eder, #[cell_name("...")] ile named cell’i seçer. Generated lifecycle’ın doldurduğu db: Arc<DatabaseService> alanı inject edilmez. Single ve factory birlikte etkinleştirilemez.
Bu sayfanın kaynakları v0.1.0
Anlatım, incelenen framework commit’ine dayanır.