Handling Data Transformation
1. Transforming Request Data
| Transformation | Example |
|---|---|
| Trim whitespace | " alice " → "alice" |
| Lowercase emails | "Alice@X.COM" → "alice@x.com" |
| Normalize phone | "(555) 123-4567" → "+15551234567" |
| Parse dates | String → LocalDateTime/Instant |
| Decode base64 | String → byte[] |
2. Transforming Response Data
| Transformation | Purpose |
|---|---|
| Entity → DTO | Hide internal fields, shape response |
| Enum → String | Serialize as readable name |
| BigDecimal → String | Avoid float precision loss |
| Lazy → eager loading | Avoid N+1 queries |
3. Implementing Data Mapping
| Tool | Language | Approach |
|---|---|---|
| MapStruct | Java | Compile-time annotation processor |
| ModelMapper | Java | Runtime reflection |
| AutoMapper | .NET | Convention-based |
| class-transformer | TypeScript | Decorator-based |
4. Converting Date Formats
| Format | Example | Use |
|---|---|---|
| ISO 8601 | 2026-05-15T10:30:00Z | Standard for APIs |
| Unix timestamp | 1747304400 | Compact, no TZ ambiguity |
| Unix millis | 1747304400000 | JS Date compatibility |
| RFC 1123 (HTTP) | Sat, 15 May 2026 10:30:00 GMT | HTTP headers only |
5. Handling Time Zones
Warning: Always store timestamps in UTC. Convert to user's TZ only at presentation layer.
| Strategy | Notes |
|---|---|
| UTC in API | Suffix Z in ISO 8601 |
| Include offset | 2026-05-15T10:30:00-05:00 |
| IANA TZ name | "timezone": "America/New_York" (separate field) |
| Avoid | Local time without offset, abbreviations (EST, PST) |
6. Sanitizing User Input
| Threat | Mitigation |
|---|---|
| XSS | HTML-escape before rendering; use CSP |
| SQL Injection | Parameterized queries / ORMs |
| NoSQL Injection | Validate object shapes; reject operators |
| Command Injection | Whitelist; never pass to shell |
| Path Traversal | Reject ../, canonicalize paths |
| Mass Assignment | Allowlist fields (DTO pattern) |
7. Implementing Case Conversion
| Conversion | Use |
|---|---|
| snake_case ↔ camelCase | Java backend ↔ JS frontend |
Jackson PropertyNamingStrategy.SNAKE_CASE | Auto-convert Java fields |
| JSON.parse with reviver | JS-side conversion |
8. Removing Sensitive Fields
| Field | Action |
|---|---|
| Password hashes | Never serialize (Jackson @JsonIgnore) |
| Internal IDs | Strip in DTOs |
| PII (SSN, DOB) | Mask or omit per role |
| Tokens / secrets | Never log or return |
Example: Field-Level Filtering (Java/Jackson)
public class User {
private Long id;
private String email;
@JsonIgnore
private String passwordHash;
@JsonProperty(access = Access.WRITE_ONLY)
private String currentPassword;
}
9. Implementing Data Enrichment
| Enrichment | Source |
|---|---|
| Computed fields | Server calculation (totals, age from DOB) |
| Resolved references | Embed related resources (?expand=author) |
| Localized labels | i18n service per Accept-Language |
| Geocoded addresses | External lookup added to response |
10. Using Transformation Libraries
| Library | Language | Purpose |
|---|---|---|
| Jackson | Java | JSON serialization, custom serializers |
| MapStruct | Java | DTO ↔ Entity mapping |
| Lombok | Java | Boilerplate reduction |
| class-transformer | TS/Node | Plain ↔ class instance |
| Marshmallow | Python | Schema-based serialization |
| Pydantic | Python | Model validation + serialization |