JAMStack in action
A modern way of building app—
Let’s create fast, responsive, secure, robust, lightweight apps with JavaScript, APIs, and Markup; serverless way.
Last week, I had the opportunity to take a session on JAMStack at KDI Bangalore. JAMStack is a revolutionary concept to change the way we design our system. At KDI Bengalore we strive to modernize the ways we design and deploy our web applications. It was therefore natural for us to look into the emerging framework JAMStack. To show the great benefits of JAMStack I will be demonstrating how you can easily build and design a Movie review website and deploying it to Azure with Azure DevOps and Azure Functions. If you want to follow along you can look at the GitHub link JAMStack.
Hence, without wasting time, let’s JAM.
- JAMStack Concept
- Overview of the technology stack
- Serverless Architecture Benefits
- Evolution of Web
- JAMStack Application Architecture
- Demo
- VS Code Capabilities
- Azure Deployment
- Extend app using Storage, Functions, Cosmos Db
- Demo
- CI/CD Setup
JAMStack Concept:
The JAMstack is not about specific set of technologies. It’s a new way of building websites and apps that delivers better performance, higher security, lower cost of scaling, and better developer experience.
Here, we can use any JavaScript presentation frameworks like angular, react, or vuejs. we have APIs which can be third party APIs or serverless functions which we will be using in this demo. And finally, we have markup which is a templated markup and together all, we get JAM.
Overview of the technology stack:
Below, I have mentioned brief picture of technology stack, which we will be using for our demo
Serverless Architecture Benefits:
In this demo, we will be using serverless concept, it doesn’t mean that we do not have server, but it means we need to think “less” about servers, hence serverless.
These are the following reasons why we have chosen serverless
- Security:- when we have fewer servers then we have a lesser concern about security as most of the heavy lifting is already taken care by vendor
- High Performance
- High Salability
- Low cost
Evolution of Web:
As you can see the left hand side image depicts the layering of traditional web app, and the stack displayed at the right hand side depicts simple JAM architecture, which is nothing but web browsers and APIs instead of web servers. Advantages of having APIs are; they can talk directly to the web browser and host it statically which is the fastest way of getting HTML up and running in the browser.
JAMStack Application Architecture:
As per architectural diagram shown above, we apply the same concept when we build the JAMStack. Now that, we have web browser as shown above in the diagram, we have something like a reverse proxy which will be available when we go live. It means it will target something to one specific URL.
We will see the same procedure in action during the demo. We use serverless functions to do this implementation that will have serverless APIs with the HTTP-Trigger function, which is used to get the list of movies. We have NOSQL database; we will be using Cosmos to store the data. We will use Angular front end and Azure storage to build this piece. This entire solution will be cloud based. This briefly makes the JAMStack.
Demo:
In order To get started with demo, let’s grab the initial skeleton code from GitHub to help you. Once you clone the repo, your source code should look something like this.
I will explain all the bits in a moment. But, before that, let’s just install that packages and run the app. First npm i to install the packages and then npm run start to run the app, because we will be proxy config in future. once we do that, it will come like this
Now, let’s go ahead and proceed with the demo. First thing let’s go ahead and build the project with npm run build. This will create “dist” folder like shown below.
Now, we will be converting this simple app as JAMStack. In case you want to see the source of these values , you can view the api folder from movies.json file.
Its pretty simple angular code wherein this data is getting served by angular service as shown below.
And movie looks like
I will not explain much here as you can explore on your own, it is just plain angular nothing fancy!
You can install these azure extensions from the marketplace. I have three elements here; storage, functions, and app service. Once we have these extensions in place, we can go ahead in functions module and click on first icon which is folder’s icon and enter the required info as shown below.
Next, we click on Browse icon as shown above, and then we create a new folder named functions as shown below.
Notice, we have kept functions folder outside of angular project directory. The reason being, these are independent components irrespective of angular dependencies. Then, we will get the following options for function creation
Here, we will choose Typescript. Then, we will get the following window to choose from.
Here, we will choose HTTP Trigger for the same. Then, I have given the function names as movies.
And lastly, we will say Authorization level as Anonymous. Once we create this function, this will drop couple of components in our source folder related to this function.
Apart from this, there are many other components dropped in the repository. We will go one by one into that. Functions folder look like this.
It has index.ts file which is basically function and binding that we can see in function.json file.
You can see from the code that the “get” and “post” functions are already configured. We can configure other http verbs as well here. Apart from that, there are few settings and launch related files which are also dropped in the repository. They are:
- extensions.json
- launch.json
- tasks.json
- host.json
- package.json
- proxies.json
- tsconfig.json
- function.json
- index.ts
- sample.dat
Many functions of many files are self explanatory. However, I will explain those which is required for demo. Now, I will remove this boiler plate code from index.ts file and replace the same with below snippet.
Here, there are few dependencies I need to install. If you see the package.json file inside functions folder, then it will be shown like this:
Here, I need to install one more package with the command npm i @azure/cosmos inside functions folder.
Once the required dependencies are installed, then, I will go ahead and put the required settings in local.settings.json file like shown below.
The setting file will be pushed in azure. This is kind of app-settings file that contains all environment related things. This is the reason, this file in the explorer is grayed out as it can’t be checked in.
At this instant, I can run the code locally as well. I can go ahead and debug as well. If we try to debug, we will see that the “attach to node function” is already there.
And this setting is coming from launch.json as shown below.
Here, I can go ahead and add many other configurations as required. So, now we can go into the debug window and click on play button. This will launch movies api locally which is basically azure function on port 7071.
Now, if I go to http://localhost:7071/api/movies
This will produce the output, as shown above. Let’s go ahead and use the same endpoint in our code. For that we will go to environment.ts file and replace the same with this endpoint.
Let’s go ahead and debug the app and this time let’s put the break-point in function get method as shown below. Once function is running locally, I will just hit the endpoint on browser, then it should hit the break-point as shown below.
Here, I have also applied watch on the result, so once I execute that line, I can see my values in the watch window as well.
At this stage, I can go ahead and bind values in my angular app also by running angular app from different cmd prompt. We can achieve from the same configuration..
Here, we have something called preLaunchTask, which is pointing to npm: start. This we can configure in tasks.json file as shown below. Here, I have configured the task. This will pick up the right file and matching to correct folder. Now, let’s say I have to run both client and server parallelly, then in that case, I have the option launch.json to attach the compounds.
With the above change in place, when I see the debugger, it will look like this.
Here, I have selected JAM-Stack-Demo as my configuration and, now, I debug the app. This will make sure both client and functions code run from the same window and I can debug the same parallel as well.
Extend app using Storage, Functions, Cosmos Db:
Now, we go ahead deploy our angular code to azure storage and also move functions on the cloud. Db is already hosted in the cloud. Let’s start with storage then.
Here, you can click on the up arrow icon; then you will get the following options as shown below.
Here, I will enter a new storage account.
Then, I will create either a new resource group or select an existing one. I will select an existing one and after that I will select the desired location from the list.
Having said that, this will start deploying required resources like shown below.
Once done, I will get a popup like this.
Here, I will click on the first button. Then I will get 2nd popup like shown below.
- Click Enter
- Enter Index.html file name in 2nd popup.
- Press Enter
After this, I will get popup to select folder from where, we would like to deploy on Azure. Hence, in this case, it already scanned dist folder. Therefore, we will select the same.
Once, we say ok, we can see at the bottom of the editor, that deployment is in process.
Once done successfully, we can see the success message at the bottom of the screen.
Now, I can go ahead and browse to the website as well https://ngjamstack.z30.web.core.windows.net/. Once we browse the same, we will see the same result as shown below.
Next, let’s go ahead and deploy functions. But, before that I will configure my proxies.json file.
So, here I am saying whatever is coming from /index/* should proxied down to the new url which is nothing but the storage account uri. Now, let’s go ahead and deploy the function app. Here, I will come and select the up arrow key.
It will ask for the name.
Once, I select a globally unique name and click enter, this will start deploying assets to azure.
Once successful, you will get a confirmation message like this.
Now, here we will click on the upload settings. This will take local settings file and apply the changes in azure functions. Once done successfully, you can see the settings tab; also, it has all the values. By default, it will be in a hidden state, but once you click the same, it will reveal the value like shown below.
Now, since the functions app deployed, let’s grab the url from
Therefore, once we browse https://ngjamstack.azurewebsites.net/api/movies we will see the same data coming from azure now.
So, we have done a quite a bit so far. We have storage app, up and running, we have client app up and running. We need to update environment value as well ( https://ngjamstack.azurewebsites.net/api/movies).
After this, we need to build the app and deploy again.
This will prompt for
Here, we need to click delete and deploy option. It will start deploying fresh build. Similarly, we will deploy function app.
Once that is done, then we can see that our app is navigating fine. We can also do CI/CD setup with the same as well.
CI/CD Setup:
Now, you can go ahead and setup your CI/CD setup from azure marketplace itself with the following link https://github.com/marketplace/azure-pipelines. This link will give you
From this page, you can configure your costing like shown below
I already have free plan set up for me. Therefore, What I can do here is I can go ahead and setup the build pipeline against my project as shown below. Also, from the same place, we can click on Azure Pipelines link. This will take us to the below page https://azure.microsoft.com/en-us/services/devops/pipelines/?nav=min
Here, I have two choices. I will select the 2nd one as I already have code available on my github repo. This way, I can directly link my repo with the pipeline. This will take me to my Azure DevOps account https://dev.azure.com/rahulsahay19. Here, I will create a new project.
I have made the visibility public by default so, that you guys can have a look at the pipeline project as well. Once it gets created, it will present the dashboard like shown below.
Now, from the left menu, I can click on Repos link,
If I am starting from scratch then probably I will clone this link in code and then get started. But, since I already have the repository on git. Hence, I just need to pull this in my VSTS account and that is via import button.
Once, I click on the import button, it will start the process of the import as shown below.
Once it’s done, then it will look like this
Now, at this stage, I can go ahead and setup build process as well. Here, I need to setup two builds; one more function app and another one for storage app. Therefore, I will click on set up build and this will take me to the below page
Here, I will first create a pipeline for angular app based on node js. Hence I selected the above template. It will take you to the Review tab as shown below:
After reviewing the same, you can go ahead and click on save and run button. This is YML based build file. You can do the same using classic editor as well. For azure function, I will do the same using the classic editor. You can choose either of these two ways.
Enter the required information and then click on Save and run button. It will start pipeline like
And if everything goes well, then it will look like
Above, you can add more tasks to it to optimize the build and it depends on the developer’s scenarios. I have just dropped the basic one without any edits. Similarly, for azure function app, you can create the same as shown below.
Upon selecting the middle one, this will drop below pre-defined tasks required for the pipeline.
Here, the only thing which I changed is the path of the functions app rather than root one like shown below.
You can give this pipeline some short suitable name as you wish or leave it like that only. Now, I will come and say, save and queue.
You can enter the required info and click the button Save & queue. This will trigger the build and queue the same as shown below.
Once, you click on the build number, it will take you to build page
After this, I have also enabled triggers as shown below.
This will make sure build will get automatically triggered if anyone pushes new build.
At the end of the build, we create a few artifacts, which we need to deploy to different environments. And to pick the artifacts, we need to have a release pipeline. Therefore, let’s go ahead and create one.
We can create on the link New pipeline, and this will take me to below page.
Here, I will select the highlighted one and click apply.
Here, I have given the name “Deploy Function App.” You can give whatever name you like, but a descriptive one makes sense. Then, I have selected required settings as shown below
I have also added the required artifacts and hence set the trigger as well as shown below:
Then, I have created an empty task and then I added Extract Files first with below settings
This is to make sure to pull the angular artifacts from the dist location. Next I have added another task to copy azure files with required settings as shown below.
Now, we can go ahead and create release with below settings
Here, I will go ahead and click on create button. This will show below message
Now, when I click on the release link, it will take me to the below Release page.
Here, I can go ahead and click on the deploy button.
Now, I will click on Deploy multiple. Here, I will select all the required dependencies and click on deploy.
Once, I click on the same, it will get queued like shown below.
Once, this gets completed, it will come like
Here, you can see that one deployment failed. Once you click on it, you can easily find out the reason.
It happened because my function app on portal some how got deleted. Therefore, I deployed the function app again. As a result, it produced below output
Closing notes:- In this post, we have covered a lot of stuff starting from JAM-Stack, to Azure Functions, Azure Storage. Then, debugging functions locally. Afterwards, we deployed the same on the cloud and then we have set up a complete CI/CD pipeline to automate our builds. Hope you enjoyed reading this article on JAMSTACK. Thanks for joining me.
Note:- I ran this entire flow on azure trial edition. It may happen that after some time, resources will not be accessible. In-case, if you have any query regarding the architecture or usage, please ask me @ https://twitter.com/rahulsahay19
We are always looking to hire talented developers that like to work on interesting new technologies.
Thanks,
Rahul Sahay