swagger icon indicating copy to clipboard operation
swagger copied to clipboard

Dynamic default values in OpenAPI spec cause unnecessary Git diffs

Open thisames opened this issue 4 months ago • 1 comments

Is there an existing issue that is already proposing this?

  • [x] I have searched the existing issues

Is your feature request related to a problem? Please describe it

When using entities/DTOs with dynamic default values (particularly new Date() for timestamp fields), the generated openapi-spec.json file changes on every application restart, even when no actual API changes have been made. This creates unnecessary Git diffs and forces developers to constantly commit schema changes.

This issue affects a significant portion of NestJS projects because:

  1. Lack of Standardized Entity Patterns Many projects don't have established conventions for handling timestamp fields. Different developers use:
// Causes the issue
@Property()
createdAt = new Date();

// Doesn't cause the issue  
@Property({ defaultRaw: 'CURRENT_TIMESTAMP' })
createdAt: Date;
  1. Common Tutorial Examples Many learning resources show the problematic pattern:

MikroORM quickstart guides showing createdAt = new Date() Stack Overflow answers with "quick fixes" Tutorial examples mixing database and application layer defaults

  1. Framework Migration When migrating from other ORMs, developers often translate patterns incorrectly

Current Problematic Behavior

Entity Example:

@Entity()
export class Plan {
  @Property({ type: types.datetime })
  createdAt = new Date(); // ← Executes on every app start
  
  @Property({ type: types.datetime, nullable: true })
  updatedAt?: Date; // ← No issue here
}

Generated Schema (changes every restart):

{
  "Plan": {
    "properties": {
      "createdAt": {
        "type": "object",
        "default": "2025-08-13T21:12:57.912Z" // Different every time
      },
      "updatedAt": {
        "format": "date-time",
        "type": "string" // Consistent
      }
    }
  }
}

Git Diff Result:

"createdAt": {
    "type": "object",
-   "default": "2025-08-13T21:12:57.909Z"
+   "default": "2025-08-17T14:21:42.004Z"
  }

Describe the solution you'd like

Add a configuration option excludeDynamicDefaults to SwaggerDocumentOptions that prevents dynamic default values from being included in the generated OpenAPI schema.

SwaggerModule.createDocument(app, config, {
  excludeDynamicDefaults: true // New option
});

Teachability, documentation, adoption, migration strategy

No response

What is the motivation / use case for changing the behavior?

1. Development Workflow Disruption

  • Unnecessary commits to schema files clutter version control history.
  • Noisy code reviews due to meaningless timestamp differences.
  • False positive changes in CI/CD pipelines waste time and resources.
  • Difficulty tracking actual API changes amidst irrelevant schema updates.

2. Team Collaboration Problems

  • Junior developers copy tutorial patterns that lead to schema churn.
  • Senior developers waste time explaining recurring schema file changes.
  • Merge conflicts arise on schema files with no functional differences.
  • Loss of confidence in automated schema validation processes.

3. Production/Deployment Issues

  • Schema differences across environments due to non-functional changes.
  • Automated deployment systems flag false positives for schema changes.
  • Unreliable API documentation caused by constantly changing examples.
  • Semantic versioning challenges due to frequent, irrelevant schema updates.

thisames avatar Aug 17 '25 20:08 thisames

Hey @thisames

I want to work on this issue under Hacktoberfest 2025. This is an interesting problem, and I'd be happy to resolve it. Could you please assign this to me under hacktoberfest?

Here is my proposed plan to implement the solution:

  • I will start by adding the new excludeDynamicDefaults boolean property to the SwaggerDocumentOptions interface.
  • Next, I will dive into the schema generation logic where class properties are analyzed.
  • I will implement a conditional check. If excludeDynamicDefaults is true, the logic will specifically look for and skip assigning default values that are instances of Date or other non-primitive types that suggest a dynamic value.
  • Finally, I will add relevant unit tests to validate the new functionality and update the documentation to explain how to use the new option.

If this not works I will try different approach

Looking forward to contributing!

krishna-singha avatar Oct 04 '25 11:10 krishna-singha