Einleitung: Warum GraphQL und Go das ideale Paar sind
\nIn der modernen Webentwicklung ist GraphQL zum Standard für die Erstellung flexibler und effizienter APIs geworden. In Kombination mit der Sprache Go (Golang), die für ihre Leistung und Einfachheit bekannt ist, erhalten Sie ein leistungsstarkes Werkzeug für die Backend-Entwicklung. In diesem Schritt-für-Schritt-Tutorial erstellen wir eine vollwertige GraphQL API in Go von Grund auf mit der beliebten Bibliothek gqlgen.
Sie erfahren, wie Sie das Projekt einrichten, das Schema definieren, Resolver implementieren und Middleware für die Authentifizierung hinzufügen. Am Ende des Artikels haben Sie eine funktionierende API, die bereit für die Integration mit jedem Frontend ist.
\n\n1. Projekteinrichtung und Installation der Abhängigkeiten
\nAls erstes erstellen wir ein neues Go-Modul und installieren die erforderlichen Pakete. Stellen Sie sicher, dass Go Version 1.18 oder höher installiert ist.
\nmkdir graphql-go-tutorial\ncd graphql-go-tutorial\ngo mod init graphql-go-tutorial\ngo get github.com/99designs/gqlgen@latest\ngo get github.com/99designs/gqlgen/graphql/introspection@latest\nJetzt initialisieren wir gqlgen im Projekt. Dieser Befehl erstellt eine grundlegende Dateistruktur:
go run github.com/99designs/gqlgen init\nNach der Ausführung sehen Sie die folgende Struktur:
\n- \n
graph/— Verzeichnis mit Schema- und Resolver-Dateien \ngraph/schema.graphqls— Definition des GraphQL-Schemas \ngraph/resolver.go— Platzhalter für Resolver \nserver.go— Einstiegspunkt der Anwendung \ngqlgen.yml— Konfiguration des Generators \n
2. Definition des GraphQL-Schemas
\nÖffnen wir die Datei graph/schema.graphqls und definieren unser Datenmodell. Als Beispiel erstellen wir ein einfaches Aufgabenverwaltungssystem (Task Manager):
type Task {\n id: ID!\n title: String!\n description: String\n status: TaskStatus!\n createdAt: Time!\n}\n\nenum TaskStatus {\n TODO\n IN_PROGRESS\n DONE\n}\n\ntype Query {\n tasks(status: TaskStatus): [Task!]!\n task(id: ID!): Task\n}\n\ntype Mutation {\n createTask(title: String!, description: String): Task!\n updateTask(id: ID!, title: String, description: String, status: TaskStatus): Task!\n deleteTask(id: ID!): Boolean!\n}\n\nscalar Time\nNach dem Speichern des Schemas starten wir die Codegenerierung:
\ngo run github.com/99designs/gqlgen generate\nDieser Befehl erstellt die Datei graph/model/models_gen.go mit Go-Strukturen und aktualisiert die Resolver.
3. Implementierung der Resolver und Geschäftslogik
\nJetzt implementieren wir die Logik in der Datei graph/schema.resolvers.go. Zuerst erstellen wir einen einfachen In-Memory-Speicher:
// In graph/resolver.go fügen wir den Speicher hinzu\ntype Resolver struct {\n tasks []*model.Task\n mu sync.Mutex\n}\n\nfunc NewResolver() *Resolver {\n return &Resolver{\n tasks: make([]*model.Task, 0),\n }\n}\nJetzt implementieren wir die Resolver für Query und Mutation:
\n// Query.Task\nfunc (r *queryResolver) Task(ctx context.Context, id string) (*model.Task, error) {\n r.mu.Lock()\n defer r.mu.Unlock()\n \n for _, task := range r.tasks {\n if task.ID == id {\n return task, nil\n }\n }\n return nil, fmt.Errorf("task not found")\n}\n\n// Mutation.CreateTask\nfunc (r *mutationResolver) CreateTask(ctx context.Context, title string, description *string) (*model.Task, error) {\n r.mu.Lock()\n defer r.mu.Unlock()\n \n task := &model.Task{\n ID: uuid.New().String(),\n Title: title,\n Description: description,\n Status: model.TaskStatusTodo,\n CreatedAt: time.Now(),\n }\n \n r.tasks = append(r.tasks, task)\n return task, nil\n}\n\n// Mutation.UpdateTask\nfunc (r *mutationResolver) UpdateTask(ctx context.Context, id string, title *string, description *string, status *model.TaskStatus) (*model.Task, error) {\n r.mu.Lock()\n defer r.mu.Unlock()\n \n for _, task