Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardize Prisma Model ID Handling for MongoDB Compatibility #469

Open
fityannugroho opened this issue Nov 23, 2024 · 0 comments
Open
Labels
breaking changes Changes that will break the current app enhancement New feature or request
Milestone

Comments

@fityannugroho
Copy link
Owner

fityannugroho commented Nov 23, 2024

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

Related issue: #308

MongoDB requires every document to have an _id field, which serves as the primary key. If this field is not explicitly defined, MongoDB automatically generates it as an ObjectId.

Prisma enforces this requirement by allowing fields to be mapped to _id using @map("_id"). However, the current approach in our schema introduces the following issues:

  1. Redundancy: Adding a separate id field mapped to _id creates unnecessary duplication in models (e.g., id and code as identifiers).
  2. Compatibility: Prisma Client generates different model structures depending on the database provider, which complicates testing and usage. For example, the id field exists in MongoDB models but not in models for other databases like PostgreSQL or MySQL.
  3. Type Safety Issues: Using Interceptor to modify response payloads (e.g., renaming _id to id) does not propagate these changes to the type system, leading to type mismatches and failed tests

Describe the solution you'd like

To streamline Prisma schema design and maintain consistency across database providers, I propose the following changes:

  1. Use an existing field (e.g., code) as the primary identifier (@id) for models like Province, Regency, District, Village, and Island.
  2. Map this primary identifier to _id for MongoDB using @map("_id"), ensuring compliance with MongoDB’s requirements.
  3. Remove the redundant id field, avoiding duplication and ensuring that Prisma Client generates uniform models across all database providers.

By implementing this solution, Prisma Client will:

  • Treat the code field as the primary key in all databases.
  • Map code to _id transparently in MongoDB without altering the type system or requiring manual transformations.

⚠️ Breaking Change Impact ⚠️

  • The id field will no longer appear in API responses. Front-end code that relies on id must be updated to use code instead.
  • Existing tests and documentation referencing id will need updates to align with the new schema design.

Describe alternatives you've considered

  1. Keep the Current id Field:

    • Continue using a separate id field for MongoDB while leaving other databases unaffected.
    • Downsides: Redundancy remains, and compatibility issues persist across the codebase and during testing.
  2. Use Interceptor-Based Transformations:

    • Keep the id field mapped to _id and use an Interceptor to rename _id to id in responses.
    • Downsides: This does not update the type system, leading to type errors and potential runtime inconsistencies.

Additional Context

Example Schema Change:

  // prisma/mongodb/schema.prisma
  model District {
-     id          String    @id @default(auto()) @map("_id") @db.ObjectId
-     code        String    @unique
+     code        String    @id @map("_id")
      name        String
      regencyCode String    @map("regency_code")
      regency     Regency   @relation(fields: [regencyCode], references: [code])
      villages    Village[]
    
      @@map("districts")
  }

Example Response Change:

  {
    "statusCode": 200,
    "message": "OK",
    "data": {
-     "id": "67416361d55864c342c96d15",
      "code": "321215",
      "name": "Indramayu",
      "regencyCode": "3212",
      "parent": {
        "regency": {
-         "id": "6741635dd55864c342c91ff5",
          "code": "3212",
          "name": "KABUPATEN INDRAMAYU",
          "provinceCode": "32"
        },
        "province": {
-         "id": "6741635cd55864c342c91f2f",
          "code": "32",
          "name": "JAWA BARAT"
        }
      }
    }
  }

Benefits:

  • Consistent schema across database providers.
  • No redundant fields or transformations.
  • Improved type safety in Prisma Client.
@fityannugroho fityannugroho added enhancement New feature or request breaking changes Changes that will break the current app labels Nov 23, 2024
@fityannugroho fityannugroho added this to the v6.0.0 milestone Nov 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking changes Changes that will break the current app enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant