GraphQL and OData in .NET

Photo by Tyler Casey on Unsplash

I was looking into Upwork jobs to see what kind of work the companies there ask people to do. I found some interesting “fixed priced” ones, like this one. I didn’t do the job, I was really just passing by. But this job asked for an ASP.NET Core MVC project where the person could do some CRUD operations and some search with pagination. So far super boring thing to do, but then the person also asked for the ability to be able to select either GraphQL or OData as the source of search. Now things get a little more interesting. I did both in the past, so I was wondering, have things got better nowadays? Surprisingly yes.

Why would I use GraphQL or OData?

If you have ever done any backend server API that needed to return some data to a frontend, I know you have thought the same question:

Which data should I return?

Usually the answer would be “ALL of them”. Even if you have done things right and your “DTO” represents only what it should, things could easily get out of control. Imagine that you have a route to get details of a device, say /api/devices/12345. So far you return:

{
"id": 12345,
"battery-level": 56,
"temperature": 23
}

You have a nice landing summary device details page in your frontend that shows device temperature and battery level. Then, due a request from the business, you must implement another page that will display the device and the reading from another sensor (that already exists in database, you are just not returning it in that details route). If you are willing to respect your REST API design, probably you would just add the field in the previous shown route or create a more specific route like /api/12345/sensor. Can you see that both decisions wont scale well? Or you will ended up with a lot of specific endpoints or with a very big json, even though not all fields are used in some parts of the system. This is the kind of problem that OData and GraphQL can help you solve, by having an endpoint (potentially, you could have more than one with OData. Not very common with GraphQL, but you could also have more than one) and the possibility to choose only what you want to return. I will not cover specifics of these technologies, if you are curious about the details of them, please check these official references:

You can find the all the source code used here in:

OData in ASP.NET core 3.1

It is quite simple to have and endpoint with OData. With your ASP.NET Core Web API created, install this package:

Install-Package Microsoft.AspNetCore.OData

I also recommend you to install NewtonsoftJson serializer, to avoid reference loops errors with the default System.Text.Json:

Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson

At your Startup.csadd the following inside you configure method:

And this inside configure services:

And here is an example of a controller that enables OData:

Here is a query to return all Products with their names and price, also it’s category and color with their respective names, and also sorting descending by price:

https://localhost:5001/odata/Products?$select=Name,Price&$expand=Category($select=name),Color($select=Name)&$orderby=Price%20desc

A return example from the query above:

First 3 products returned from the query

GraphQL in ASP.NET core 3.1

We have a lot of different implementations for GraphQL. I have used graphql-dotnet in the past and it’s up and running in production. So, to see the difference of usage, I decided for Hotchocolate, another very good implementation of GraphQL. Again, with your ASP.NET Core Web API created, install this packages:

Install-Package HotChocolate
Install-Package HotChocolate.AspNetCore
Install-Package HotChocolate.Types.Filters
Install-Package HotChocolate.Types.Sorting

Also you need to configure your Startup.cs:

I used what Hotcholate calls “Pure Code-first”, because I found it quite simple and really close to how to configure OData. Product, Color and Category in the above code sample are the exposed models that I want in my Schema. ProductQueries are the queries available in the Schema, which looks like this:

And that’s it, you have a GraphQL endpoint to test. I did the most “do less” thing I could, so don’t expected security or anything. You can customize your Schema pretty much you like. Here is a sample query returned (just like the OData above):

The query in the left and some results in the right

Which one should I choose?

I knew that question would come. First, OData and GraphQL it’s not .NET specific technologies, both are standard protocols implemented in various languages and frameworks. Now, back to the question, as a wise man once told me:

It depends.

I, personally, prefer the way GraphQL works. I had a lot of headache with OData, specially with the size of the request URL when we needed to add a substring filter. But this is a personal preference, so here is what you must have in your mind when deciding:

  • OData uses REST pattern to operate, which means PUT/PATCH, GET, POST, DELETE have meaning in the kind of operation you want to do.
  • OData uses the URL to build the query, so be careful with the size of your request.
  • GraphQL is transport agnostic, but most common is HTTP with POST only. The query is passed as body content in the request and has it’s own “definition”. Even if you want to get something from the server, you have to do a POST.
  • There is no official GraphQL implementation from Microsoft, but the available libraries does a pretty good job. The two most used are Hotchocolate and graphql-dotnet. I used graphql-dotnet in production but an older version (.net core 2.2).
  • GraphQL has an introspection endpoint which makes easy to find tools to connect and see your published schema (like the Banana Cake Pop from Hotcholate).
  • GraphQL is hard to cache, but possible. From Apollo’s blog:

“As we saw, (cache) it is not out of question with GraphQL, it is simply not as powerful as for highly optimized/one-size-fits-all APIs because of how often a query can be invalidated and how little can be shared.”

So what do you think? Would you give GraphQL or OData a try? Again, you can find the source code in my github:

Leave your feedback, it would be very interesting to see your experiences with both technologies. Stay tuned for more in the future.

Software Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store