Skip to content

Commit 2637982

Browse files
committed
!
1 parent 37ca8ca commit 2637982

2 files changed

Lines changed: 157 additions & 2 deletions

File tree

TROUBLESHOOTING_NOTES.md

Lines changed: 156 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,33 @@ pub struct ListParams {
175175

176176
**Notlar:**
177177
- `#[param(...)]` attribute'u RustAPI'de yok
178-
- Validation kuralları için `validator` crate kullan:
178+
- Validation kuralları için RustAPI'nin built-in validation sistemini kullan:
179179
```rust
180+
use rustapi_validate::Validate;
181+
180182
#[derive(Debug, Deserialize, Validate, Schema)]
181183
pub struct CreateTask {
182184
#[validate(length(min = 1, max = 200))]
183185
pub title: String,
186+
#[validate(email)]
187+
pub email: String,
188+
}
189+
190+
// Handler'da ValidatedJson kullan
191+
async fn create_task(
192+
Json(task): ValidatedJson<CreateTask>
193+
) -> Result<Json<Task>> {
194+
// Validation otomatik yapılır, hata varsa 400 döner
195+
Ok(Json(task.into_inner()))
184196
}
185197
```
186198

199+
**RustAPI Validation Özellikleri:**
200+
- `ValidatedJson<T>` - Otomatik validation + JSON parsing
201+
- `#[validate(...)]` attribute'ları rustapi-validate'den gelir
202+
- Validation hataları otomatik olarak formatlanır
203+
- Built-in validators: length, email, range, url, regex, custom, vb.
204+
187205
---
188206

189207
### 5. **Handler Macro Kullanımı**
@@ -291,6 +309,143 @@ async fn handler() -> Html<String> { // ✅ Concrete type
291309

292310
---
293311

312+
### 7. **DateTime<Utc> Schema Sorunu**
313+
314+
**Sorun:**
315+
```rust
316+
#[derive(Debug, Serialize, Schema)]
317+
pub struct BookmarkResponse {
318+
pub id: u64,
319+
pub created_at: DateTime<Utc>, // ❌ RustApiSchema implement etmiyor
320+
pub updated_at: DateTime<Utc>,
321+
}
322+
```
323+
```
324+
error[E0277]: the trait bound `DateTime<Utc>: RustApiSchema` is not satisfied
325+
```
326+
327+
**Çözüm:**
328+
DateTime'ı String olarak kullan ve RFC3339 formatında dönüştür:
329+
330+
```rust
331+
#[derive(Debug, Serialize, Schema)]
332+
pub struct BookmarkResponse {
333+
pub id: u64,
334+
pub created_at: String, // ✅ String kullan
335+
pub updated_at: String,
336+
}
337+
338+
// From/Into implementasyonunda dönüştür:
339+
impl From<&Bookmark> for BookmarkResponse {
340+
fn from(b: &Bookmark) -> Self {
341+
Self {
342+
id: b.id,
343+
created_at: b.created_at.to_rfc3339(), // DateTime -> String
344+
updated_at: b.updated_at.to_rfc3339(),
345+
}
346+
}
347+
}
348+
```
349+
350+
**Alternatif - Unix Timestamp:**
351+
```rust
352+
#[derive(Debug, Serialize, Schema)]
353+
pub struct BookmarkResponse {
354+
pub created_at: i64, // Unix timestamp (seconds)
355+
}
356+
357+
impl From<&Bookmark> for BookmarkResponse {
358+
fn from(b: &Bookmark) -> Self {
359+
Self {
360+
created_at: b.created_at.timestamp(),
361+
}
362+
}
363+
}
364+
```
365+
366+
**Neden?**
367+
- `chrono::DateTime<Utc>` RustAPI'nin Schema trait'ini implement etmez
368+
- OpenAPI spec'inde date-time'lar genellikle RFC3339 string formatındadır
369+
- Client tarafında parse etmek daha kolay (JavaScript, Python, etc.)
370+
- String representation timezone bilgisini de içerir
371+
372+
**Best Practice:**
373+
- Response DTO'larda `String` kullan (RFC3339 format)
374+
- Internal model'lerde `DateTime<Utc>` kullan
375+
- Dönüşümü From/Into trait'leriyle yap
376+
377+
---
378+
379+
### 8. **Generic Type'larda Schema Trait Bound**
380+
381+
**Sorun:**
382+
```rust
383+
#[derive(Debug, Serialize, Schema)]
384+
pub struct PaginatedResponse<T> { // ❌ T için trait bound eksik
385+
pub items: Vec<T>,
386+
pub total: usize,
387+
}
388+
```
389+
```
390+
error[E0277]: the trait bound `T: RustApiSchema` is not satisfied
391+
```
392+
393+
**Çözüm:**
394+
Generic type'a `RustApiSchema` trait bound ekle:
395+
396+
```rust
397+
#[derive(Debug, Serialize, Schema)]
398+
pub struct PaginatedResponse<T: rustapi_openapi::schema::RustApiSchema> { // ✅ Trait bound
399+
pub items: Vec<T>,
400+
pub total: usize,
401+
pub page: u32,
402+
pub limit: u32,
403+
}
404+
405+
// Kullanım:
406+
async fn list_items() -> Json<PaginatedResponse<ItemResponse>> {
407+
// ItemResponse: Schema derive'ına sahip olmalı
408+
Json(PaginatedResponse {
409+
items: vec![],
410+
total: 0,
411+
page: 1,
412+
limit: 20,
413+
})
414+
}
415+
```
416+
417+
**Alternatif - Type Alias:**
418+
```rust
419+
// Generic yerine concrete type'lar için type alias
420+
pub type BookmarkList = PaginatedResponse<BookmarkResponse>;
421+
pub type CategoryList = PaginatedResponse<CategoryResponse>;
422+
423+
async fn list_bookmarks() -> Json<BookmarkList> {
424+
// ...
425+
}
426+
```
427+
428+
**Neden?**
429+
- `Vec<T>` RustApiSchema implement eder, ancak `T` de RustApiSchema olmalı
430+
- Compiler, `T`'nin hangi trait'leri implement ettiğini bilmeli
431+
- OpenAPI spec oluştururken concrete type bilgisi gerekli
432+
433+
**Trait Bound Şablonu:**
434+
```rust
435+
// ✅ Tam trait path
436+
T: rustapi_openapi::schema::RustApiSchema
437+
438+
// ✅ Import ile kullanım
439+
use rustapi_openapi::schema::RustApiSchema;
440+
T: RustApiSchema
441+
442+
// ✅ Prelude'dan
443+
use rustapi_rs::prelude::*;
444+
T: RustApiSchema
445+
```
446+
447+
---
448+
294449
## 📋 Checklist: Yeni Bir Handler Eklerken
295450

296451
- [ ] Query params struct'ına `Schema` derive ekle
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"rustc_fingerprint":10447247078198843705,"outputs":{"7971740275564407648":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\tunay\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"cmpxchg16b\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"pc\"\nwindows\n","stderr":""},"17747080675513052775":{"success":true,"status":"","code":0,"stdout":"rustc 1.91.0 (f8297e351 2025-10-28)\nbinary: rustc\ncommit-hash: f8297e351a40c1439a467bbbb6879088047f50b3\ncommit-date: 2025-10-28\nhost: x86_64-pc-windows-msvc\nrelease: 1.91.0\nLLVM version: 21.1.2\n","stderr":""}},"successes":{}}
1+
{"rustc_fingerprint":5892572920467916005,"outputs":{"7971740275564407648":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\tunay\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"cmpxchg16b\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"pc\"\nwindows\n","stderr":""},"12004014463585500860":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\tunay\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"cmpxchg16b\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_has_atomic=\"128\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"pc\"\nwindows\n","stderr":""},"17747080675513052775":{"success":true,"status":"","code":0,"stdout":"rustc 1.91.0 (f8297e351 2025-10-28)\nbinary: rustc\ncommit-hash: f8297e351a40c1439a467bbbb6879088047f50b3\ncommit-date: 2025-10-28\nhost: x86_64-pc-windows-msvc\nrelease: 1.91.0\nLLVM version: 21.1.2\n","stderr":""}},"successes":{}}

0 commit comments

Comments
 (0)