GraphQL vs REST in C#: Kampf der Titanen oder Werkzeugwahl für die Aufgabe?
\n\nHallo, Kollegen! Wenn Sie in C# programmieren und APIs erstellen, ist die Frage "REST oder GraphQL?" sicherlich schon mehr als einmal aufgekommen. Es ist wie die Debatte, was besser ist: ein Hammer oder ein Akkuschrauber. Beides sind Werkzeuge, aber für unterschiedliche Aufgaben. In diesem Artikel werden wir nicht fanatisch eine Technologie verteidigen, sondern nüchtern mit C#-Codebeispielen analysieren, wann GraphQL gewinnt und wann das gute alte REST der König bleibt.
\n\nWir sind das Team von PythonLib, und obwohl "Python" im Namen steht, lieben wir das .NET- und C#-Ökosystem. Heute werfen wir einen Blick in die Welt der APIs in C# und finden heraus, wie man bei der Wahl keinen Fehler macht. Los geht's!
\n\nKurze Einführung: REST und GraphQL für C#-Entwickler
\n\nREST (Representational State Transfer) ist ein Architekturstil, den wir alle kennen und lieben. In C# verwenden Sie wahrscheinlich ASP.NET Core Web API. Sie erstellen Controller, Endpunkte, und jeder Endpunkt gibt eine feste Datenstruktur zurück. Sie möchten einen Benutzer abrufen? Gehen Sie zu /api/users/1. Sie möchten seine Bestellungen? Gehen Sie zu /api/users/1/orders. Einfach, vorhersagbar, führt aber oft zu Over-Fetching (Sie erhalten unnötige Daten) oder Under-Fetching (Sie müssen mehrere Anfragen stellen).
GraphQL ist eine von Facebook entwickelte Abfragesprache. In der C#-Welt wird es durch Bibliotheken wie Hot Chocolate (die beliebteste) oder GraphQL.NET implementiert. Sie haben einen Endpunkt (normalerweise /graphql), und der Client entscheidet selbst, welche Felder er benötigt. Sie möchten den Namen des Benutzers und nur die erste Bestellung? Bitte sehr! Kein Over-Fetching.
Praktischer Vergleich: C#-Code
\n\nGehen wir von der Theorie zum Code über. Stellen wir uns vor, wir haben ein einfaches Modell: User und Order.
// Datenmodelle\npublic class User\n{\n public int Id { get; set; }\n public string Name { get; set; }\n public string Email { get; set; }\n public string Phone { get; set; }\n public List<Order> Orders { get; set; }\n}\n\npublic class Order\n{\n public int Id { get; set; }\n public string ProductName { get; set; }\n public decimal Price { get; set; }\n public DateTime CreatedAt { get; set; }\n}\n\n\nBeispiel einer REST-API mit ASP.NET Core
\n\n[ApiController]\n[Route("api/[controller]")]\npublic class UsersController : ControllerBase\n{\n [HttpGet("{id}")]\n public async Task<ActionResult<User>> GetUser(int id)\n {\n // Angenommen, die Daten kommen aus der DB\n var user = await _dbContext.Users.FindAsync(id);\n if (user == null) return NotFound();\n return Ok(user); // Gibt ALLE Felder zurück: Id, Name, Email, Phone, Orders\n }\n}\n\n\nProblem? Wenn der Client nur den Namen und die E-Mail benötigt, erhält er trotzdem Phone und Orders. Und wenn Bestellungen benötigt werden, muss eine separate Anfrage an /api/users/1/orders gestellt werden.
Beispiel einer GraphQL-API mit Hot Chocolate
\n\npublic class Query\n{\n public async Task<User> GetUser(int id, [Service] AppDbContext dbContext)\n {\n return await dbContext.Users.FindAsync(id);\n }\n}\n\n// Registrierung in Program.cs\nbuilder.Services\n .AddGraphQLServer()\n .AddQueryType<Query>();\n\n\nJetzt kann der Client genau das anfordern, was er braucht:
\n\n// GraphQL-Abfrage\n{\n user(id: 1) {\n name\n email\n orders {\n productName\n price\n }\n }\n}\n\n\nDie Antwort enthält nur name, email und ein Array von orders mit den Feldern productName und price. Kein überflüssiger Datenmüll. Wunderbar!
Wann REST in C# gewinnt (und das ist in Ordnung)
\n\n1. Einfachheit und Caching. REST-APIs lassen sich leicht auf HTTP-Ebene cachen (CDN, Proxy). Eine GET-Anfrage an /api/products kann gecached werden, und alle b