This is an overview of the technologies that have made up this website up until very recently and the new technologies that were transitioned to along with some of the reasoning behind the decisions to move to these technologies. Additionally, the trade-offs of moving to these modern web paradigms will be discussed.
The previous architecture represented the typical, old school way of doing web servers. A virtual machine(VM) sitting in some server farm or on premise with a server application listening on port 80 and serving up an html web page for the root url and serving data for the web page on the api url (/api). The database was also living on this VM and listened on another port for requests coming from localhost. There was also only one code repository that housed both the frontend and backend applications.
There was not much of a decision making process behind choosing these particular technologies other than that they were the Hot Technologies™ at the time that this project was conceived in early 2017. AWS as a cloud provider was and still is the top dog in that arena so choosing they’re VM offering was a prudent choice. The combination of MongoDB, Express, Angular, and Node or the MEAN stack, was very much in vogue at the time. This is not to say that one should choose technologies for an architecture of an application based on what is hot but I was a fairly fresh software engineer and was still using floaties in regards to web development. Some nice, but unintended benefits of choosing the hottest technologies is they look great on a résumé and there tends to be a lot of information on how to implement them, ala StackOverflow.
No CORS
Since both the API and the web page were served from the same VM and therefore IP address and therefore, and most importantly, and in my case, domain there was no messing around with trying to set up CORS headers to allow the web page to call the API. This made a lot of things that I took for granted just work such as calling to the API in my frontend application. If you are not familiar with CORS, MDN has a nice primer.
Very simple
Having all the parts of the full application sitting on the same VM made everything a lot easier to reason about and troubleshoot. Anything that could possiby go wrong would be captured in the application logs as everything was in the same place and then I could go ahead and fix it right then and there.
Deployment
Not exactly a part of the architecture, but tangential to all applications, is how it was being deployed. Being a new software engineer I did not give this much thought, which was a big mistake. The easier and faster your deployments are the more likely you are to ship. My deployment for this app was all manual and went something like this:
git pull origin development
npm run start
Unfortunately, a good 50% of the time I would forget something I had done during local development that was not a part of source control and I would sit there cussing away at the damn thing as if it wasn’t my fault. This lead to me dreading pushing out new code and discouraged me from writing new code.
Content
You should not have to deploy to release new content. You should not have to deploy to release new content. I wish I would have been aware of this timeless piece of advice when I was defining how this blog would work. I thought it would be brilliant to have my blogposts be in source control along with my code and have the db just reference the file on the server. Boy, was I wrong. Having my blogposts in source control by itself is not a bad idea but just not in the same repo as the code. Which is what I have transitioned to now. Requiring a deployment for new content was doubly bad because of how fraught with peril these deployments were as discussed in the previous point.
Server and DB Management
I am a developer at heart. I do not exactly want to be having to prop up databases and ensuring the VM’s packages are up to date. Obviously, sometimes these are duties that have to be undertaken as a developer but they are certainly not what I want to be spending my time doing. Having to do these things as a part of having a web facing application was always a bit of a bother.
I moved the entire application over to Microsoft Azure because I had a lot of experience using its services through my previous job and had become very familiar with the Azure Portal. The frontend is a rewrite of the original in VueJS with, I think, a more modern, simplistic layout. The new frontend is housed in blob storage. The backend is the same Node app just refactored and improved a bit to make it a more restful API as well as more of a true content management system(CMS) in order to increase the ease of interacting with it from multiple frontends as I now also have an admin portal for the app. The Node app now sits within an App Service Web App because there were no changes that needed to be made and was largely just a lift and shift. I also moved from MongoDB to CosmosDB because I didn’t want to manage my own database anymore and because CosmosDB has a MongoDB API. So, I was able to interact with CosmosDB from my Node app without changing any code, just the connection strings.
Deployment
Now that this application sits completely in Azure, Microsoft’s Devops suite of applications Azure Devops makes building and deploying to Azure just about as easy as it gets. Now all the repositories related to this application get built automatically on commits and can be deployed with the click of the button.
Price
As soon as work you normally have to do gets abstracted away you can only assume that more money is being spent somewhere. This rule holds with this new serverless paradigm, my original single VM architecture cost ~$10 a month and the new architecture costs ~$40 a month with Azure’s database as a service CosmosDB making up the vast majority of that cost. The Cosmos DB instance I have is almost the smallest one you can possibly get, 600 RUs per second, and it cost $33.48 last billing cycle.
Not fully supported
As this new architecture is pretty close to bleeding edge there are still some things that are a little awkward or not quite supported. For instance, the routing for the Vue app is a bit of a hack because browser based routing for SPA apps is not supported in static websites in blob storage in Azure at the time of this writing. So, currently, the error page is just pointed to the same index.html as a successful request in the configuration. When initially navigating to the website, if the page is not the home page, a 404 will be returned before the browser gets redirected to the “error” page and then the client side routing will handle getting the user to the right page.
The majority of this transition was done in order to maximize what I enjoy doing, programming using the latest and greatest technologies even if it is at the expense of some money and support. Thanks for reading and if you have any questions or concerns regarding this post please create on issue on Github. As always, happy hacking!
Just your typical coffee addicted software engineer. Exploring the intracacies and whimsies of the web, one cup at a time.
This is an overview of the technologies that have made up this website up until very recently and the new technologies that were transitioned to along with some of the reasoning behind the decisions to move to these technologies. Additionally, the trade-offs of moving to these modern web paradigms will be discussed.
The previous architecture represented the typical, old school way of doing web servers. A virtual machine(VM) sitting in some server farm or on premise with a server application listening on port 80 and serving up an html web page for the root url and serving data for the web page on the api url (/api). The database was also living on this VM and listened on another port for requests coming from localhost. There was also only one code repository that housed both the frontend and backend applications.
There was not much of a decision making process behind choosing these particular technologies other than that they were the Hot Technologies™ at the time that this project was conceived in early 2017. AWS as a cloud provider was and still is the top dog in that arena so choosing they’re VM offering was a prudent choice. The combination of MongoDB, Express, Angular, and Node or the MEAN stack, was very much in vogue at the time. This is not to say that one should choose technologies for an architecture of an application based on what is hot but I was a fairly fresh software engineer and was still using floaties in regards to web development. Some nice, but unintended benefits of choosing the hottest technologies is they look great on a résumé and there tends to be a lot of information on how to implement them, ala StackOverflow.
No CORS
Since both the API and the web page were served from the same VM and therefore IP address and therefore, and most importantly, and in my case, domain there was no messing around with trying to set up CORS headers to allow the web page to call the API. This made a lot of things that I took for granted just work such as calling to the API in my frontend application. If you are not familiar with CORS, MDN has a nice primer.
Very simple
Having all the parts of the full application sitting on the same VM made everything a lot easier to reason about and troubleshoot. Anything that could possiby go wrong would be captured in the application logs as everything was in the same place and then I could go ahead and fix it right then and there.
Deployment
Not exactly a part of the architecture, but tangential to all applications, is how it was being deployed. Being a new software engineer I did not give this much thought, which was a big mistake. The easier and faster your deployments are the more likely you are to ship. My deployment for this app was all manual and went something like this:
git pull origin development
npm run start
Unfortunately, a good 50% of the time I would forget something I had done during local development that was not a part of source control and I would sit there cussing away at the damn thing as if it wasn’t my fault. This lead to me dreading pushing out new code and discouraged me from writing new code.
Content
You should not have to deploy to release new content. You should not have to deploy to release new content. I wish I would have been aware of this timeless piece of advice when I was defining how this blog would work. I thought it would be brilliant to have my blogposts be in source control along with my code and have the db just reference the file on the server. Boy, was I wrong. Having my blogposts in source control by itself is not a bad idea but just not in the same repo as the code. Which is what I have transitioned to now. Requiring a deployment for new content was doubly bad because of how fraught with peril these deployments were as discussed in the previous point.
Server and DB Management
I am a developer at heart. I do not exactly want to be having to prop up databases and ensuring the VM’s packages are up to date. Obviously, sometimes these are duties that have to be undertaken as a developer but they are certainly not what I want to be spending my time doing. Having to do these things as a part of having a web facing application was always a bit of a bother.
I moved the entire application over to Microsoft Azure because I had a lot of experience using its services through my previous job and had become very familiar with the Azure Portal. The frontend is a rewrite of the original in VueJS with, I think, a more modern, simplistic layout. The new frontend is housed in blob storage. The backend is the same Node app just refactored and improved a bit to make it a more restful API as well as more of a true content management system(CMS) in order to increase the ease of interacting with it from multiple frontends as I now also have an admin portal for the app. The Node app now sits within an App Service Web App because there were no changes that needed to be made and was largely just a lift and shift. I also moved from MongoDB to CosmosDB because I didn’t want to manage my own database anymore and because CosmosDB has a MongoDB API. So, I was able to interact with CosmosDB from my Node app without changing any code, just the connection strings.
Deployment
Now that this application sits completely in Azure, Microsoft’s Devops suite of applications Azure Devops makes building and deploying to Azure just about as easy as it gets. Now all the repositories related to this application get built automatically on commits and can be deployed with the click of the button.
Price
As soon as work you normally have to do gets abstracted away you can only assume that more money is being spent somewhere. This rule holds with this new serverless paradigm, my original single VM architecture cost ~$10 a month and the new architecture costs ~$40 a month with Azure’s database as a service CosmosDB making up the vast majority of that cost. The Cosmos DB instance I have is almost the smallest one you can possibly get, 600 RUs per second, and it cost $33.48 last billing cycle.
Not fully supported
As this new architecture is pretty close to bleeding edge there are still some things that are a little awkward or not quite supported. For instance, the routing for the Vue app is a bit of a hack because browser based routing for SPA apps is not supported in static websites in blob storage in Azure at the time of this writing. So, currently, the error page is just pointed to the same index.html as a successful request in the configuration. When initially navigating to the website, if the page is not the home page, a 404 will be returned before the browser gets redirected to the “error” page and then the client side routing will handle getting the user to the right page.
The majority of this transition was done in order to maximize what I enjoy doing, programming using the latest and greatest technologies even if it is at the expense of some money and support. Thanks for reading and if you have any questions or concerns regarding this post please create on issue on Github. As always, happy hacking!