Heim >Backend-Entwicklung >Golang >Reduzieren Sie die Menge an doppeltem Code beim Zuordnen von DTOs in Go
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
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 }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, } }
type TagHandler struct { store specifications.TagStore } func NewTagHandler(store specifications.TagStore) TagHandler { return TagHandler{ store: store, } }
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) } }
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) } }
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 }
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?
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) } }
Dann wirst du
habenfunc (h TaskHandler) List() http.HandlerFunc { return ListHandler("tasks", h.store.ListTasks) } func (h TagHandler) List() http.HandlerFunc { return ListHandler("tags", h.store.ListTags) }
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!