Building My First API From Scratch
Tags: api, dotnet, csharp, rest
Published: 2020-04-20 15:31:00

Photo by Glen Carrie on Unsplash

*Originally published on my blog at [halldorstefans.com](https://www.halldorstefans.com/building-my-first-api-from-scratch/) on April 20, 2020*

Recently I joined a small group within my company, and we aimed to improve the Integration API for a specific product.

The problem was that under a specific load, the API threw a bunch of errors.

But I had a problem of my own.
The API architecture was way more complicated than I had encountered in [online tutorials](https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.1&tabs=visual-studio).
I, therefore, didn't understand how it all worked and wondered if I would be able to contribute anything to this task.

## How do I get the knowledge I need?

This opportunity was something I found interesting and had offered my help, so I was eager to contribute to it.
But seeing that it was going to be more complicated than I thought, I wondered if I was going to be wasting everyone's time.

I knew that I learn things quicker if I'm able to build them on my own.
But was there going to any time for me to do that? What would I even build?

Building the whole API, similar or part of it would be too big and time-consuming. And I would probably end up copy-pasting already existing code and learn nothing.

So I started to exploring online what kind of API projects people were doing.
It was hard to find a project of the right size. Too small and straightforward and I wouldn't learn much, but too big would be time-consuming and the high possibility of being way over my head and drop the project.
I then came across the [Pokémon API](https://pokeapi.co/) by [Paul Hallett](https://twitter.com/phalt_).
A project like these seemed to be an ideal fit as a side project for me.
Even though the API only has GETs, I was confident that I could create an API with a bit more complicated architecture than the typical beginners' tutorials. Might be overkill, but so be it.

## How am I going to build it?

I still had some questions that I needed to figure out. What data could I provide? How could I build this API similar to my company's API?

During my research on API projects, I came across something called "Clean Architecture".
Being somewhat of a minimalized and having read Clean Code by Robert Martin not long ago, this appealed to me straight away.
Plus this architecture was not far from how my company's API was structured.

I found all kinds of [articles](https://fullstackmark.com/post/18/building-aspnet-core-web-apis-with-clean-architecture), [videos](https://www.youtube.com/watch?v=_lwCVE_XgqI), and [GitHub repos](https://github.com/ardalis/CleanArchitecture). I gathered as much as I could find on the topic, to help me understand it.

But still, I wasn't programming anything yet because I hadn't figured out what my API would produce.
It needed to be something I would be interested in; otherwise, I had the feeling I wouldn't be able to follow this project through.
I looked at my interests and what data was available in those areas.

Being a football(soccer)/Manchester United fan, I started looking in that area. Just looking at the English Premier League, I thought that was way too big.
I could narrow it down just to Man United. But even then, I wondered how much data I needed to gather. All the players in the clubs' history, their stats, all the games? Even that seemed too big.

What other interested to I have? Cars, I like cars. Could I gather information about one manufacturer and all the models that manufacture has created? Maybe.
How about racing? Formula 1, perhaps? Is there any data on my favourite team in F1, McLaren? Hmm... [this Wikipedia page](https://en.wikipedia.org/wiki/McLaren_Grand_Prix_results) is interesting.

When I saw this page, I thought this could be perfect. I had all the races McLaren has taken part in and their result.
I could even have a separate table for the cars and drivers, and have some information on them.

I then noticed where Wikipedia was getting this data from, and ended up on [STATS F1](https://www.statsf1.com/en/mclaren.aspx).
It was perfect. There was the data I wanted and structured.
I, therefore, used that as my data structure. Awesome

## Now, I could start programming

So I started on the Core layer.
Investigating all the Github repos I had found, and figuring out what was supposed to be where and how.

Once I had roughly finished that part, I moved to the Infrastructure layer and then eventually the Web layer.
Developing this was, of course, a bit of iterative progress, going back and forth in layers, fixing, adjusting and such.

But, all this helped me better understand how the different layers were connected, deepening my knowledge of interfaces, getting more familiar with Entity Framework and LINQ.

There was also a bit of frustration in this process (like always), especially around the naming of things.

For example, items named '[UseCases](https://github.com/mmacneil/CleanAspNetCoreWebApi/tree/master/src/Web.Api.Core/UseCases)', '[Services](https://github.com/Tillman32/CleanArchitecture/tree/master/src/CleanArchitecture.Core/Service)' and '[Supervisor](https://github.com/cwoodruff/ChinookASPNETCore3APINTier/tree/master/ChinookASPNETCore3APINTier/Chinook.Domain/Supervisor)' in different Github repos, all seemed to be doing the same action.
But why are they named differently? Is there no convention on the naming of items or standards? I don't understand.

It can sometimes be hard to identify if things are doing the same thing, or something completely different when trying to learn new things.
In cases like this, I usually then focus on one solution and follow that. Once I understand that solution, I review the other solutions and see if they start making sense.

I was finally able to make everything work together. It was such a great feeling when I was finally able to get that 200 response back.
What a beauty!

## Job done, almost

It was a little bit tempting to say the project was over at that time.
I had achieved what I wanted.
Learned more about APIs and understood better what I was working on in work.

But I wanted to keep the momentum going, so I decided to add versioning, Swagger documentation and some tests.

The versioning and Swagger part was pretty straight forward. I found useful documentation from Microsoft, and it helped a lot.

*Finding this was great because one of the tasks of improving the Integration API at work was to research and possible implement versioning. Which in the end I did implement :)*

Now toward the last bit, testing.

Adding testing to the project was going to be the final piece of the puzzle.
I had never used xUnit before but wanted to learn more, so this seemed like an excellent opportunity.

Even though the repositories I found on Clean Architecture had some tests, I wanted to see also other examples.
I did a bit of research and found some great resources, for example, [this article](https://timdeschryver.dev/blog/how-to-test-your-csharp-web-api) and [this repository](https://github.com/exceptionnotfound/XUnitMockTestsDemo).

I then started on the unit tests.
After some time working on them, they weren't producing the results I wanted, so I wanted to skip doing the tests.
Creating some tests, when the fun part is done, on some side project that possible no know is going to use. Why am I doing this?
But I managed to plough through and get them to work.
I still have some doubts about my unit tests and if they are entirely acceptable tests, but better than nothing, right?

## Keep going

In the end, I managed to build an API with clean architecture. I even managed to have versioning, documentation and tests. If you're curious how it looks at the moment, [here is the GitHub repo](https://github.com/halldorstefans/McLarenAPI)

Damn, I was proud.

I know building a project can be frustrating but don't give up. It's such a great feeling when you finally manage to finish it.
Thank you for reading and keep ongoing

---

Thank you for reading. For weekly updates from me, you can sign up to my [newsletter.](https://email.halldorstefans.com/)