Skip to content
GGemini Kim
  • Home
  • Articles
  • About
KO/EN

Articles

Notes, essays, and observations.

  1. December 28, 2024

    Reader and Writer Are Options, Not Architecture Rules

    Choose Reader, Writer, and tool-layer boundaries from code size, domain distance, legacy constraints, and team conventions—not imitation.

    • Architecture
    Read ↗
  2. December 21, 2024

    The Common Module Trap: Organize Code Around Concrete Capabilities

    Delay common modules until ownership is clear, and organize logging, exceptions, and shared protocols around concrete capabilities instead.

    • Architecture
    • Testing & Quality
    Read ↗
  3. December 15, 2024

    Join the Team Before You Try to Change It

    Adapt to a new engineering team through timely questions, visible progress, early review, and small evidence-based changes after trust is earned.

    • Career & Learning
    • Collaboration
    Read ↗
  4. December 8, 2024

    How to Break Up a Giant Service Class Without Guesswork

    Split an oversized service by mapping concepts, tracing responsibilities, testing boundaries, and comparing concrete refactoring options.

    • Architecture
    • Testing & Quality
    Read ↗
  5. December 1, 2024

    Keep Operational Tables Clean by Building a Separate Query Model

    Design operational tables around business concepts, then serve complex history and admin searches from a separate query model.

    • Architecture
    • Data & Persistence
    Read ↗
  6. November 24, 2024

    Enums or Code Tables? Let the Rate of Change Decide

    Use enums for stable values and focused tables for frequently changing ones without turning one common-code table into a dumping ground.

    • Domain Modeling
    • Data & Persistence
    Read ↗
  7. November 18, 2024

    One Database, Separate Boundaries: Controlling Data Access by Domain

    How separate entity and repository boundaries can protect core rules from integration code even when both areas share one database table.

    • Architecture
    • Domain Modeling
    • Data & Persistence
    Read ↗
  8. November 11, 2024

    Append, Don’t Overwrite: Designing Immutable Operational Data

    An append-only repayment example that makes history and synchronization clearer, along with the storage and query costs it introduces.

    • Data & Persistence
    • Reliability & Operations
    Read ↗
  9. November 4, 2024

    What a Utility Bill Can Teach Us About Domain Modeling

    How a utility bill revealed a missing delinquency concept in a repayment model and why everyday artifacts can guide software design.

    • Architecture
    • Domain Modeling
    • Career & Learning
    Read ↗
  10. October 28, 2024

    Rank Your Domain Concepts Before You Spend Design Effort

    Identify a small first tier of domain concepts, separate supporting flows, and spend limited design time on the service's center.

    • Architecture
    • Domain Modeling
    • Career & Learning
    Read ↗
  11. October 22, 2024

    Experience, Repetition, and the Developer Who Keeps Growing

    How varied experience, repeated attempts, and business awareness help developers solve unfamiliar problems and keep improving.

    • Career & Learning
    Read ↗
  12. October 15, 2024

    Before Fixing Circular Dependencies, Fix the Domain Model

    Resolve confusing ownership and concept boundaries before using interfaces or dependency inversion to treat an apparent circular reference.

    • Architecture
    • Backend Engineering
    • Domain Modeling
    Read ↗
  13. October 8, 2024

    Create a Deliberate Messy Boundary to Keep the Core Clean

    Contain unavoidable complexity in an explicit outer boundary so limited engineering time can protect the system's core concepts.

    • Architecture
    • Testing & Quality
    Read ↗
  14. October 1, 2024

    Nullable or Zero? Choosing a Kotlin JPA Entity ID Strategy

    Compare nullable and zero-valued numeric IDs for Kotlin JPA entities, including new-entity detection, ambiguity, and verification.

    • Backend Engineering
    • Data & Persistence
    Read ↗
  15. September 25, 2024

    CS Knowledge Becomes Valuable When It Solves Real Problems

    Learn computer science through real engineering problems, then show the reasoning and improvements it made possible in your work.

    • Career & Learning
    Read ↗
  16. September 18, 2024

    Layering That Teammates Can Understand—and the Build Can Enforce

    Define stable layer roles, constrain optional upper layers, and automate checks only when a team needs stronger enforcement.

    • Architecture
    • Testing & Quality
    Read ↗
  17. September 11, 2024

    Turn Production Incidents into Shared Domain Knowledge

    Use incident reviews, working notes, concept maps, and rotated operations to reduce domain knowledge gaps across a software team.

    • Domain Modeling
    • Reliability & Operations
    • Collaboration
    Read ↗
  18. September 4, 2024

    One Project, Many Deployables: Drawing Boundaries by Runtime Role

    Separate public, admin, batch, and operations workloads into runnable applications without splitting the whole codebase into separate projects too early.

    • Architecture
    • Backend Engineering
    • Delivery & Evolution
    Read ↗
  19. August 29, 2024

    Name Readers, Finders, and Searchers by Behavior

    Distinguish Reader, Finder, and Searcher classes by direct reads, added filtering, and composite searches rather than result count.

    • Architecture
    • Backend Engineering
    • Testing & Quality
    Read ↗
  20. August 22, 2024

    Measure Before Replacing Outbox Polling

    Evaluate outbox polling with realistic load tests, then consider a simpler application-level delivery path before adopting log tailing.

    • Architecture
    • Domain Modeling
    • Performance & Scale
    Read ↗
  21. August 15, 2024

    Publish Events Where the Business Flow Is Visible

    Place event publication in the layer that understands the completed business action, while keeping implementation-specific cases explicit.

    • Architecture
    • Domain Modeling
    Read ↗
  22. August 9, 2024

    Compose My Page Data Without Inventing a My Domain

    Build My page summaries through a dedicated composition layer while keeping user, order, and product responsibilities in their proper domains.

    • Architecture
    • Backend Engineering
    • API Design
    Read ↗
  23. August 2, 2024

    Modules, Layers, and Architecture Are Different Decisions

    Separate module boundaries from code-level layers and architectural style, then extract modules only when implementation needs stronger constraints.

    • Architecture
    Read ↗
  24. July 26, 2024

    Earn Your Interfaces: Abstraction After Evidence

    Start with concrete code, extract interfaces from proven variation, and keep one-to-one abstractions only when they create a real boundary.

    • Architecture
    • Testing & Quality
    Read ↗
  25. July 19, 2024

    Choose Hexagonal Architecture for a Reason

    Choose hexagonal architecture when protocols, isolation, scale, or likely growth justify its extra structure—not because the label signals skill.

    • Architecture
    Read ↗
  26. July 13, 2024

    Track Database Changes with the Work That Ships Them

    Collect database changes with the issue and PR that need them, test them in development, and hand off the final release set before code deployment.

    • Data & Persistence
    • Reliability & Operations
    • Delivery & Evolution
    Read ↗
  27. July 6, 2024

    Authorization Without Redundant Reads

    Resolve the logged-in user once, keep access checks focused, and separate system-wide administration from channel-level permissions.

    • Architecture
    • API Design
    • Testing & Quality
    Read ↗
  28. June 29, 2024

    Design for Change with Core Ownership and Surrogate Keys

    Centralize a shared registration rule in the core, escalate isolation only when needed, and keep changing business uniqueness out of the primary key.

    • Architecture
    • Data & Persistence
    Read ↗
  29. June 22, 2024

    Why a My Page Is Not a Domain

    A My Page is a client-facing view, not a business domain. Keep orders, products, and coupons with their real owners and combine them at the boundary.

    • Backend Engineering
    • Domain Modeling
    • API Design
    Read ↗
  30. June 16, 2024

    Software Is Not Done Until It Is Deployed

    Stale pull requests and delayed releases make changes harder to review, deploy, diagnose, and roll back. Keep the path to production short and observable.

    • Delivery & Evolution
    Read ↗
  31. June 9, 2024

    Separate Shared Counts from Personalized Cache State

    Compose a reaction status from reusable queries, then cache the shared count without leaking one member’s personalized state to everyone else.

    • Architecture
    • Performance & Scale
    Read ↗
  32. June 2, 2024

    What Repeated Failure Teaches a Developer Career

    Career failures become useful when they change how you verify opportunities, value trusted referrals, and revise the rules you made from earlier setbacks.

    • Reliability & Operations
    • Career & Learning
    Read ↗
  33. May 26, 2024

    One Read Model for Guests and Members

    Return public reaction counts and member-specific state through one read flow while keeping optional identity distinct from required authentication.

    • Architecture
    • API Design
    Read ↗
  34. May 20, 2024

    Rebuild First, Migrate Second

    Design a replacement system around the problems it must solve, then handle legacy data through explicit migration mappings and retirement conditions.

    • Architecture
    • Data & Persistence
    • Delivery & Evolution
    Read ↗
  35. May 13, 2024

    Modeling Reactions from Requirements to Scale

    Turn a vague like-button request into a reaction model by clarifying policy, estimating data growth, and planning when count queries must change.

    • Architecture
    • Data & Persistence
    • Performance & Scale
    Read ↗
  36. May 6, 2024

    Designing Domain Models Beyond the Shape of the UI

    A tree-shaped API does not require a tree-shaped domain. Keep the client contract at the presentation boundary and compose it from internal concepts.

    • Architecture
    • Backend Engineering
    • API Design
    Read ↗
  37. April 30, 2024

    Put Logic Where Change Is Cheapest: Client vs. Server

    Place display-only work near the UI, but centralize meaningful or changing values when multiple clients and shipped app versions make updates expensive.

    • API Design
    • Delivery & Evolution
    Read ↗
  38. April 23, 2024

    Don't Distort Production Code Just to Make Tests Easier

    Change production code when its behavior becomes clearer or legacy code needs a testing seam—not merely to expose values or methods that only tests use.

    • Testing & Quality
    • Delivery & Evolution
    Read ↗
  39. April 16, 2024

    Modernize Legacy Systems Gradually—and Treat Caches as Operations

    Choose legacy boundaries carefully, change them in small steps, and add a shared cache only after DB work and deployment failure modes are understood.

    • Reliability & Operations
    • Performance & Scale
    • Delivery & Evolution
    Read ↗
  40. April 9, 2024

    Reversible Design Is the Antidote to Overengineering

    Build the requirement in front of you, look only a little beyond it, and keep speculative structures cheap to expand, remove, or replace.

    • Architecture
    • Data & Persistence
    Read ↗
  41. April 3, 2024

    Win Technical Arguments with Small Proofs, Not Opinions

    Diagnose why a proposal is blocked, build a small proof, strengthen your reasoning, understand the opposing case, and treat new technology as company risk.

    • Architecture
    • Collaboration
    Read ↗
  42. March 27, 2024

    A Practical Entry Strategy for a Frozen Junior Developer Market

    In a tight 2024 hiring market, broaden the first-company search, turn real work into problem-solving evidence, and show reasoning rather than a technology list.

    • Career & Learning
    Read ↗
  43. March 20, 2024

    Build APIs for Clarity, Not REST Purity

    Use REST ideas where they improve an HTTP contract, but let client clarity, team consistency, domain boundaries, and change cost decide the API.

    • API Design
    Read ↗
  44. March 13, 2024

    Validate at the Boundary, Simplify the Core

    Turn API input into complete business values at the presentation boundary, keep nulls out of inner flows, and validate stored data when it enters the system.

    • Architecture
    • API Design
    Read ↗
  45. March 7, 2024

    From SI to Product Development: Turn Job Requirements into a Learning Plan

    A move from contract work to a product team depended on help and luck; the repeatable strategy is to study target job requirements and build relevant experience.

    • Career & Learning
    Read ↗
  46. February 29, 2024

    Your First Test Can Be Messy—Refactor It Later

    Start with the test that proves the behavior you care about, mock enough to make it run, and improve test design through repeated use and review.

    • Backend Engineering
    • Testing & Quality
    Read ↗
  47. February 22, 2024

    Keep API Request Models Out of the Core Domain

    Convert external request objects into business-owned values at the presentation boundary so the API depends inward and the core never depends back.

    • Architecture
    • Backend Engineering
    • API Design
    Read ↗
  48. February 15, 2024

    Design Performance Tests from Real Traffic Shapes

    Estimate volume and arrival patterns before choosing a load test, add deliberate headroom, and require evidence only where traffic risk justifies it.

    • Testing & Quality
    • Reliability & Operations
    • Performance & Scale
    Read ↗
  49. February 9, 2024

    Foreign Keys Are an Operational Tradeoff, Not a Rule

    Choose foreign keys, indexes, and ORM mappings from integrity needs, incident response, deployment practice, and who operates the database.

    • Backend Engineering
    • Data & Persistence
    • Reliability & Operations
    Read ↗
  50. February 2, 2024

    Give Cross-Domain Behavior to the Domain That Owns It

    Before placing a caller-owned interface across modules, identify which domain owns the action and let callers depend on that capability.

    • Architecture
    • Backend Engineering
    • Domain Modeling
    Read ↗
  51. January 26, 2024

    Who Owns the Enum? Dependency Design Across Domain Modules

    Put a business enum with its domain, let storage depend inward, and use a small shared enum module only while the domain boundary is still emerging.

    • Architecture
    • Backend Engineering
    Read ↗
  52. January 19, 2024

    Provider Identity and Authentication Boundaries for Platform APIs

    How a small platform API resolves provider keys into a domain identity, separates tenant data, and chooses an authentication boundary that fits its scale.

    • Architecture
    • Backend Engineering
    • API Design
    Read ↗
  53. January 13, 2024

    Where Cross-Domain Coordination Code Belongs

    Use business ownership, cohesion, imports, and a package-move experiment to place code that coordinates a primary action with another domain's rule.

    • Architecture
    • Domain Modeling
    Read ↗
  54. January 6, 2024

    Domain Models First: A Conservative Approach to JPA Associations

    A cautious way to map JPA entities: start with IDs, add associations only when lifecycles truly align, and model business concepts independently.

    • Backend Engineering
    • Domain Modeling
    Read ↗
  55. December 9, 2023

    You Can Practice High-Traffic Engineering Without Real Traffic

    Build and operate a small service, create load deliberately, and show how you found and fixed bottlenecks without pretending a load test equals production experience.

    • Backend Engineering
    • Performance & Scale
    • Career & Learning
    Read ↗
  56. December 4, 2023

    Reliable Database Tests Without a Shared Test Database

    Choose mocks, an in-memory database, Testcontainers, or a real database by the failure you need to catch, while keeping ordinary tests isolated from shared infrastructure.

    • Backend Engineering
    • Data & Persistence
    • Testing & Quality
    Read ↗
  57. November 30, 2023

    Do Not Create a DTO for Every Layer by Habit

    Use DTOs where data crosses a boundary with a different contract. Mapping has a cost, but so does letting external request shapes define the inside of a service.

    • Architecture
    • Backend Engineering
    • API Design
    Read ↗
  58. November 25, 2023

    Git History Is a Team Asset, Not a Work Diary

    Split work before polishing commits, shape pull requests for reviewers, and leave a history that helps the next engineer understand changes and recover a release.

    • Delivery & Evolution
    • Career & Learning
    • Collaboration
    Read ↗
  59. November 21, 2023

    Put Circuit Breakers Next to the Failing I/O

    Circuit breakers, timeouts, cache fallbacks, and remote-call policies belong near the implementation that performs the I/O, while domain code chooses the required behavior.

    • Architecture
    • Backend Engineering
    • Reliability & Operations
    Read ↗
  60. November 16, 2023

    Timeouts Are Product Decisions, Not Just Client Settings

    Design timeout, retry, and recovery policies from the user's waiting budget and the uncertainty of each failure instead of applying one retry rule everywhere.

    • Backend Engineering
    • Reliability & Operations
    Read ↗
  61. November 12, 2023

    Do Not Split Modules Before the Domain Has Matured

    Domain maturity comes from understanding policy, behavior, and operating reality. Let those lessons reveal module boundaries instead of freezing guesses too early.

    • Architecture
    • Backend Engineering
    • Domain Modeling
    Read ↗
  62. November 7, 2023

    Grow Software One Boundary at a Time

    Start with working code, then extract functions, classes, packages, modules, and projects as real cohesion and scale make each stronger boundary necessary.

    • Architecture
    Read ↗
  63. November 2, 2023

    Keep Layers Logical and Packages Cohesive

    Modules, packages, and architectural layers solve different problems. Package related behavior together and let layers describe roles without scattering a feature.

    • Architecture
    Read ↗
  64. October 29, 2023

    Upgrade Dependencies Before the Gap Becomes a Project

    Frequent, prioritized dependency upgrades keep change small, expose compatibility problems early, and prevent a maintained service from quietly accumulating debt.

    • Backend Engineering
    • Delivery & Evolution
    Read ↗
  65. October 24, 2023

    Software Should Survive the Developer Who Built It

    Good company software reduces debt, fits the team's operating ability, and remains understandable and repairable after its original developer leaves.

    • Architecture
    • Testing & Quality
    • Collaboration
    Read ↗
  66. October 20, 2023

    Unit Tests Should Preserve Business Intent

    A business-layer unit test is useful when it guides design, records meaningful behavior, or makes the next developer reconsider a risky change.

    • Architecture
    • Testing & Quality
    Read ↗
  67. October 15, 2023

    When an AI Agent Calls the Same Tool Twice

    Retries are normal in distributed systems and AI workflows. Use database constraints, idempotency keys, and bounded retries to prevent duplicate side effects.

    • Backend Engineering
    • Reliability & Operations
    Read ↗
  68. October 11, 2023

    Multi-Module Too Early Makes Design Harder

    Modules should enforce boundaries discovered through implementation, not freeze guessed domains or mirror an architecture diagram before the software is understood.

    • Architecture
    Read ↗
  69. October 6, 2023

    Gradle Dependency Scopes Are Architectural Boundaries

    Use Gradle implementation, api, runtimeOnly, and compileOnly deliberately to express module access, prevent accidental coupling, and preserve design intent.

    • Architecture
    • Backend Engineering
    Read ↗
  70. October 2, 2023

    Operate Your Toy Project Before Calling It a Service

    A toy project becomes service experience only after launch: pick one goal, find real users, watch retention, and learn when to stop.

    • Reliability & Operations
    • Career & Learning
    Read ↗
  71. September 27, 2023

    Isolate Admin Work from the Service Domain

    Admin APIs have different queries, mutation needs, and release risks. Isolate them by module or repository instead of letting operational convenience reshape the core service.

    • Architecture
    • Backend Engineering
    Read ↗
  72. September 22, 2023

    Use Reader and Writer Components to Reveal Business Flow

    Reader and writer components can hide storage details, narrow change, and let the business layer show policy, but only when the software's lifetime justifies them.

    • Architecture
    • Backend Engineering
    • Testing & Quality
    Read ↗
  73. September 18, 2023

    Carry One Trace ID across Distributed Services

    Logs become operationally useful when one request can be followed across HTTP calls and asynchronous events without exposing sensitive data or flooding storage.

    • Backend Engineering
    • Reliability & Operations
    Read ↗
  74. September 13, 2023

    Define Problems from the User's Perspective

    Problem-solving improves when you separate technical load from product value, launch what you build, and keep asking why a user would choose it.

    • Career & Learning
    Read ↗
  75. September 9, 2023

    Reuse Below the Use-Case Layer

    When use cases call one another for reuse, business changes spread and cycles follow. Compose above them or extract focused implementation components below them.

    • Architecture
    • Backend Engineering
    Read ↗
  76. September 4, 2023

    Choose Experience and Judgment over Development Jargon

    Theories and patterns are useful references, but a developer still needs to explain the code, its tradeoffs, and what happened when it was operated.

    • Architecture
    • Career & Learning
    • Collaboration
    Read ↗
  77. August 31, 2023

    How to Split a Large Service Class by Responsibility and Layer

    Use constructor dependencies and imports to diagnose an oversized service, then separate cohesive responsibilities before adding another architecture label.

    • Architecture
    • Backend Engineering
    • Testing & Quality
    Read ↗
  78. August 26, 2023

    Choose Normalization from Requirements and Object Relationships

    Database normalization is not a score to maximize. Decide from change semantics, query cost, and the relationships the data is meant to preserve.

    • Architecture
    • Backend Engineering
    • Data & Persistence
    Read ↗

© 2026 Gemini Kim

RSSGitHubLinkedInXYouTube