Skip to content

Refactor: decouple sqlc-generated DB models from domain logic #156

@TheJolman

Description

@TheJolman

the dbmodels package (generated by sqlc) is used pretty much everywhere in the codebase, which makes it hard to change things when the DB changes.

This exposes things like sql.NullString to clients, which they shouldn't have to deal with.

An example - while working on #144, I had to modify the DB models and it required that I change stuff throughout the entire codebase, CLI and everything despite it just being a change to the database.

After doing some research, something like this is standard:

HTTP Request (DTOs)
    ↓
Handler Layer (DTOs ↔ Domain Models)
    ↓
Service Layer (Domain Models)
    ↓
Repository Layer (Domain Models ↔ DB Models)
    ↓
Database (sqlc-generated DB Models)

DTOs are Data Transfer Objects. They're outward facing and only exist to move data around. This lets us control what fields are exposed in the API.

Domain models are for internal use and should replace the usage of db models in places like the CLI.

The repository layer is an abstraction that essentially translates db models into domain models.

Order of tasks:

  1. Add domain models in internal/domain package for each db table. Only use standard Go types for these.
  2. Add repository layer at internal/api/repository. The dbmodels package should be kept internal to this package.
  3. Create API DTOs at internal/dto/request and internal/dto/response. I'm suggesting NOT putting them within the API package due to Allow JSON input in CLI #152 . These should all have JSON tags.
  4. Update service layer to work with domain models. Should call repositories instead of stuff from dbmodels.
  5. Update handlers to use DTOs for input/output.
  6. Update CLI to use domain models instead of dbmodels.
  7. Update docs and potentially unit test for translation layers.

Metadata

Metadata

Assignees

Labels

0 - ADVANCEDExtensive research + significant amount of time/effort requiredapiRelating to the API onlyhigh prioHigh priority. Important or blocking bug/feature.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions