The last time I did any web backend development in earnest was back in about 2001, before I went off to University, and was in PHP on Apache!
(Well, that’s mostly true; I also did some stuff with self-hosted IIS and ASP.net for work, to authenticate some in-app purchases for a phone-game… but there really wasn’t that much to that.)
One of the things that has always bothered me about web development (at least back in the day) is how opaque a lot of the stack is and how the code you write was really limited to what the framework would allow you to do. A whole bunch of the code would be written one way because “that’s how you do it in this framework” and it never felt like you were creating from the ground up in any meaningful sense, just schlocking together bits and pieces of provided functionality to make your own sites.
For my normal bread-and-butter, C++ game development, having that kind of freedom to build things is an easy case, you just write both ends of the connection and handle all of the traffic yourself (including encoding/decoding/reliability/etc). You are one hundred percent in-control and you can write arbitrary code. But that idea falls apart once you don’t control both ends of the connection, and as soon as one end of the connection can be something like a web-server, you need to start handling web-standards and it gets really messy and becomes a full-time job keeping your server up to date with the ever-changing web-standards and technologies.
What I really always wanted was a minimal thin layer, that could sit on top of a web-server and just expose ‘endpoints’ (like functions), handling just the connection (inc. SSL etc) and any parameter-passing, and from that point onwards 100% of the code that’s executed within those endpoints/functions could be your own, and could do anything the language supported. This would let me write my own versions of straight-forward services that I’d be happy to self-host, and the endpoints could return data or dynamically generated web-pages as-required.
With all of the advances in ease-of-use frameworks for web development and Internet-of-Things proliferation (including things like NodeJS or AWS’s lambda frameworks and authentication services), I figured there must be a simpler way to do this these days…
So when I was on my Sabbatical (June->Sept 2022) I made a point of having a little dig around to see what was out there.
It quickly became apparent that there were some good frameworks available built on top of Python (Django, FastAPI, Flask), and as I’d learned Python a lot of years ago (as part of a previous sabbatical, where I learned Python and Autonomous drone flight, amongst other things) I thought that would be a perfect excuse to brush up the old Python skills and dive in.
I gave myself a good week to deep-dive re-learn Python, PIP virtual workspaces, and all of that good stuff, as it had been several years… as well as to learn my way around VSCode, and then I started out with a framework called Django.
Django:

https://www.djangoproject.com/
Django seemed at first glance to do everything I needed; it was a self-contained framework for hosting your own sites and services, it could do REST-api style functionality and generate dynamic pages and much much more…
… but it quickly became apparent that Django was not the ‘thin’ layer I was looking for. The framework was powerful, but rigid. It offered lots of cool features for data-binding and the such, but there were specific ways of doing specific things within that framework, it was lacking the “most of the code running is my own” feeling. Most of the code was Django itself, doing things behind the scenes, with some little bits of your own code tacked-on. It’s more for enterprise-level hosting than the cheap-and-cheerful REST-api services I was looking to make for myself, and so after a week or so I abandoned this idea.
(Now before people complain, yes I am aware that there’s a django-rest-framework that can be found at https://www.django-rest-framework.org/ but having looked into that, it still seemed a bit too rigid for my liking).
FastAPI:

The next framework I discovered was FastAPI, and this was exactly what I was looking for. You could write a ~5 line python program, host it with a uvicorn server, and have your end point up and running, and from that point onwards every bit of code you wrote was your own.
Sure, FastAPI was doing some cool things in the background; the decorator setup for your endpoints was handling massaging parameters and return data, auto-generating documentation, and other bits… but for the purposes of your program the only thing you were seeing was your own python file and about 99% your own code.
And on top of that, the code you write is in no way limited; you can do anything that you can do in Python, use any packages (once they’re installed), read and write any files, host databases, generate HTML pages, fire off additional web-requests, anything you want really.
As you might be able to tell, this is the solution that I ended up running with; I built out a test api to act as a sort of ‘crib-sheet’ of functionality (currently hosted on the http “apitest” subdomain of this site, although it probably won’t be up forever)… and then once I’d done that I built two real-world use-cases for it, one for interfacing with a robot (post to follow), and one for hosting an encrypted games library for an emulator I was writing (post to follow!)
I would highly recommend FastAPI (or Flask, see below) for anyone looking to host their own services with a REST API with the minimal amount of code in your project that isn’t your own.
… so what about Flask?
Flask:

https://flask.palletsprojects.com/
So it wasn’t until AFTER I’d written my API bits with FastAPI that I actually discovered Flask was a thing.
Syntactically Flask and FastAPI are extremely similar, including how quickly you can get an API up and running (just a few lines of code) and how you can host it locally for testing etc.
It seems like Flask actually came first, and is powering several large-scale websites (including Netflix!), and FastAPI came later and is a bit of a rising star, but it is clearly modelled after Flask, and even uses a lot of the same packages (e.g. HTML templates are handled by Jinja2).
The main advantage I could see touted for FastAPI was that it had better support for AsyncIO and was more lightweight (hence the ‘Fast’ bit). Oh, and the generated documentation is pretty awesome too.
That said, Flask had several advantages of its own; beyond being more industry tested and battle-hardened, when I started looking for hosting solutions (before hosting it myself), I noticed that a lot of services out there had out of the box Flask hosting, but no hosting for FastAPI.
As an example, Azure Web App hosting has Flask as an option (the spooled up VM would presumably install what was necessary for the framework and configure endpoints etc), whereas there was no such option for FastAPI.
Really though, for my own use-cases, either Flask or FastAPI would have done the trick, and the next time I go to build a web backend I’ll take a proper look at Flask as well.
Hosting:
So in the past I’ve used a lot of Amazon Web Services; I hosted my own Perforce server there and used it for some indie-game collaboration, so I was familiar with setting up and managing Elastic Compute instances.
This time though, I thought I would take a look at Microsoft Azure for Virtual Machine hosting, and give that a little go!

My initial impressions were not super favourable; there’s a learning curve on AzureVMs that doesn’t really exist with AWS, and it took a while to get things started, assign storage, and configure the firewalls so that I could access the ports necessary for the web-server etc, and between that and some SAS issues with Azure Storage Explorer there were definite frustrations… but I persisted with it and eventually got it working just fine.
There were some nice things to it, e.g. every VM gets a static IP by default (that you can route a subdomain A-Record to), and it’s quite easy to set up public-facing storage that you can use for static resources, or to write ‘results’ of processing to and then return a link to (if not confidential), and being able to Remote-Desktop in is also quite handy for working with it like it’s just a normal local PC (although to be fair you could do that on AWS EC2 instances running Windows too).
The main downsides are that it’s a little pricey (the smallest instance is costing me about £15/mo, most of which is the drive they use to store the OS!), and the lowest instance type is woefully underpowered, being assigned 1GB of memory but the OS uses about 900MB of that!
I don’t really feel like the OS partition or base memory usage (assuming you don’t install anything on it) should be factored into the allowance, but that’s just my 2 cents. If they’d said £15/mo for 100MB of memory to play with, it’s a different value proposition! (Of course this works out better for larger instances where any extra is all yours, but those are £40/mo and up, which isn’t worth it for me to just host some little API bits)
At any rate, I stuck with it (for now) and the apitest subdomain currently points to an Azure hosted VM that is mostly stable and responsive, and I can use it for quick tests as/when I need to, which is really nice.
That said, I will be looking into something like linode or other VPS offerings in the future; I’m comfortable with Linux and SSH so for hosting something like a web server with a REST API a flat £5/mo fee and more resources could be a winner. At the very least I plan to experiment with it when I get some time.
… and that’s it for now for my adventures in REST API hosting. It’ll crop up in future posts so I thought it would be good to briefly cover it all the same, and for anyone looking to host their own web backends this will hopefully contain some interesting pointers for where to start.


Leave a comment