Web API: A Song of Trial and Error
The Middle Man
It is easy to leap from input to output when it comes to data. Anyone could draw a bar chart based on a spreadsheet.
When anyone does that they become the equivalent of a Web API without knowing it. They look at what needs to presented, they trawl the spreadsheet for the correct group of information and then return to the bar chart and with that information in hand. Only then can someone begin to work.
I've written posts about the front end of a Web Service, a variety of situations involving data, I've written about retrieving data from an API that I have then used to overlay information on a Google Map.
You can probably see where this is going, I've used them, designed things with the use of an API in mind. Until recently however I hadn't rolled my sleeves up and built my own. I made many mistakes, turned out builds that were completely and hopelessly inept at their desired function.
Now, however I have something that works exactly how I want, something that can do the whole range of Create, Read, Update and Delete (CRUD).
Lessons Learned
The Big One
Direction is really important, it's no use setting out to plan and build a Web API without being at least 95% sure of what it needs to do for you and anything that interacts with it.
I'm close to doubling down and posting a multi-part overview of the project this API was built for. The mistakes and successes of that work came very much so due to initially having a poor idea of what I wanted and needed to build, that was the entire project and not just the API.
By meticulously planning out the source of your data and what the final product of your API needs to be you can save yourself an astounding amount of pain and frustration, never mind the dozens of StackOverflow visits every hour when your API isn't behaving the way you need it to.
Mistakes are going to happen. Embrace them.
At various points throughout building this API I made amateur-hour mistakes. The code review was full of disbelief at some of the poor approaches I took to achieving the desired effect within Controllers or Models in the API.
At the time, these methods were operational, they definitely worked how I wanted it to do things, looking back now I can shake my head in disbelief as well. Refactoring code is hard when you don't know better ways to approach things and more often than not the best way to learn is to fail. You're failure is only complete when you don't learn from it. In this case it wasn't a case of a slight misuse of a method that could have been solved another way, it was a complete failure to understand manipulating data in a correct and clear way.
On to the good stuff
This Web API takes HTTP calls to do it's work. POST, GET, PUT and DELETE. These correspond to the CRUD functions.
POST sends a JSON object containing all of the information that a record holds, this object is built from user inputs to create a new record in the database. When the JSON object arrives it maps itself to the "Update" object and it's properties and that object is then used to construct an INSERT statement in the database and write a new record.
GET retrieves a group of 15 records from a database when given a page number and delivers those back to the web page to be displayed in a table. Each of these 15 records is added to a list of Record objects and they are then returned to the webpage as a JSON object.
PUT receives a specific record, however that record comes with new information that the API must tell the database to update with. As with POST this JSON object is used map a new Update object that in turn is used to construct an UPDATE statement where the UpdateID of the record is passed in the WHERE clause to change that record only.
DELETE receives one thing, the UpdateID of the record the user on the front end is trying to delete, a simple DELETE statement WHERE the UpdateID is matched is deleted, this is unique across the CRUD functions of the API as doesn't require any objects to be constructed, the only thing being passed in is an int value.
Routing
With ASP.NET there is an option to change how API calls work from the front-end. In the case of this particular API, first the API's host is listed, then the API, then the controller, then the method. Optionally the user can pass in an integer at the end of this call as data. A final URI (Uniform Resource Identifier) would look like such: "www.examplehost.com/api/updates/delete/4".
This URI would result in the API deleting the record with an ID of 4.
Routing is controlled by the designer of the API, I could have set up those URI components in any order I wanted just to mess with people but alas such things are frowned upon.
The worst possible Analogy...
I spent far too long thinking of a way, in layman's terms of how I feel about the interaction between a Web API and the Front End it is being used by.
So, imagine if you will that the front end is a screw and the API is a screwdriver. You have the screw you want to use and you look into your toolbox to see what screwdriver will get the job done. If you reach in blindly and pick out the first screwdriver you find, you've got a pretty big chance that it won't work, a small chance of picking out something that will do the job adequately and an even small chance of nailing it first time.
Understand that this works both ways, if you're using a Web API that has been around for years you may need to change the screw to get the front end to work.
The better a match for your Front-End the API you use or design is the less hoops you have to go through to get to where you need to be. It's always worth checking out alternatives to see if what you're using isn't what's right for the job.
Conclusion
It's a weird and wonderful thing to be at the stage of my training where I can be asked to visualise, plan, design and code a full web service, albeit a fair amount of poor work going into that service. It's in equal parts a measure of how far I've come in the past year and of how much more ground there is to cover ahead as I go on from here, there are new things to learn in C# every time I try something new. As I often repeat myself saying, it is up to me to try to cover that ground moving forward.
One full year, it's hard to think about the sheer density of things that have happened both in work and personally over that time since I first turned up to Antelle. I'd like to think good things about that time for the most part, ignoring the flooding of our old office of course. I prefer to look back on struggling with the first HTML assignments, of getting my first web page finished just a few months later. I think I'm settled and in a position to push myself further and start helping with other projects more, to see more of how the most complex projects are designed and planned.
Until the next time, thanks for reading.