Reduzieren Sie die Menge an doppeltem Code beim Zuordnen von DTOs in Go

WBOY
Freigeben: 2024-02-06 09:00:05
nach vorne
535 Leute haben es durchsucht

在 Go 中映射 DTO 时减少重复代码的数量

Frageninhalt

Ich lerne gerade Go und würde mich über die Erkenntnisse der Leute freuen, wie man die Menge an doppeltem Code am besten reduzieren kann.

Die Ordnerstruktur der relevanten Teile ist wie folgt:

.
├── http
│   ├── handlers
│   └── routes
├── models
│   └── dto
├── specifications
└── store
    └── postgres
Nach dem Login kopieren

In meinem specations-Ordner habe ich 2 „Speicher“-Schnittstellen:

type TaskStore interface {
    CreateTask(ctx context.Context, input dto.TaskCreate) error
    UpdateTask(ctx context.Context, id int, input dto.TaskUpdate) error
    GetTask(ctx context.Context, id int) (dto.TaskResult, error)
    ListTasks(ctx context.Context) ([]dto.TaskResult, error)
    DeleteTask(ctx context.Context, id int) error
}

type TagStore interface {
    CreateTag(ctx context.Context, input dto.TagCreate) error
    RenameTag(ctx context.Context, id int, input dto.TagUpdate) error
    ListTags(ctx context.Context) ([]dto.TagResult, error)
    GetTag(ctx context.Context, id int) (dto.TagResult, error)
    DeleteTag(ctx context.Context, id int) error
}
Nach dem Login kopieren
Der Ordner

store/postgres enthält die Implementierung von Aufgaben und Tags (Repository-Muster).

Fragen, die ich sehe:

In meinem handlers-Ordner habe ich eine Struktur, die Eingaben von einer der Speicherschnittstellen entgegennimmt:

type TaskHandler struct {
    store specifications.TaskStore
}

func NewTaskHandler(store specifications.TaskStore) TaskHandler {
    return TaskHandler{
        store: store,
    }
}
Nach dem Login kopieren
type TagHandler struct {
    store specifications.TagStore
}

func NewTagHandler(store specifications.TagStore) TagHandler {
    return TagHandler{
        store: store,
    }
}
Nach dem Login kopieren

Diese Handler enthalten Methoden, die API-Pfaden zugeordnet werden:

func (h TaskHandler) List() http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        tasks, err := h.store.ListTasks(r.Context())
        if err != nil {
            log.Err(err).Msg("failed to retrieve tasks")
            w.WriteHeader(http.StatusInternalServerError)
            return
        }
        render.JSON(w, r, tasks)
    }
}
Nach dem Login kopieren
func (h TagHandler) List() http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        tags, err := h.store.ListTags(r.Context())
        if err != nil {
            log.Err(err).Msg("failed to retrieve tags")
            w.WriteHeader(http.StatusInternalServerError)
            return
        }
        render.JSON(w, r, tags)
    }
}
Nach dem Login kopieren

Sie werden feststellen, dass die List Methoden auf jedem Handler grundsätzlich gleich sind, mit Ausnahme der Schnittstelle, die von jedem Geschäft verwendet wird.

Wie ändere ich diese Einstellung, um doppelten Code zu reduzieren?

Ich dachte zunächst, ich könnte Generika verwenden, um dieses Problem zu lösen, zum Beispiel:

type EntityStore[CreateDto any, UpdateDto any, ResultDto any] interface {
    Create(ctx context.Context, input CreateDto) error
    Update(ctx context.Context, id int, input UpdateDto) error
    List(ctx context.Context) ([]ResultDto, error)
    Get(ctx context.Context, id int) (ResultDto, error)
    Delete(ctx context.Context, id int) error
}
Nach dem Login kopieren

Aber das bedeutet, jeden Typ einem Handler zuzuordnen, was meiner Meinung nach keine praktische Lösung ist.

Irgendwelche Vorschläge, wie ich meine DTOs und Schnittstellen besser abbilden kann?


Richtige Antwort


Sie können eine Hilfsfunktion haben

func ListHandler[T any](name string, lister func(ctx context.Context) ([]T, error)) func(w http.ResponseWriter, r *http.Request) {
    return func(w http.ResponseWriter, r *http.Request) {
        list, err := lister(r.Context())
        if err != nil {
            log.Err(err).Msg("failed to retrieve " + name)
            w.WriteHeader(http.StatusInternalServerError)
            return
        }
        render.JSON(w, r, list)
    }
}
Nach dem Login kopieren

Dann wirst du

haben
func (h TaskHandler) List() http.HandlerFunc {
    return ListHandler("tasks", h.store.ListTasks)
}

func (h TagHandler) List() http.HandlerFunc {
    return ListHandler("tags", h.store.ListTags)
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonReduzieren Sie die Menge an doppeltem Code beim Zuordnen von DTOs in Go. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!