1569318636
You might be seeing the term JAMstack popping up more and more frequently. I’ve been a fan of it as an approach for some time.
One of the principles of JAMstack is that of pre-rendering. In other words, it generates your site into a collection of static assets in advance, so that it can be served to your visitors with maximum speed and minimum overhead from a CDN or other optimized static hosting environment.
But if we are going to pre-generate our sites ahead of time, how do we make them feel dynamic? How do we build sites that need to change often? How do we work with things like user generated content?
As it happens, this can be a great use case for serverless functions. JAMstack and Serverless are the best of friends. They complement each other wonderfully.
In this article, we’ll look at a pattern of using serverless functions as a fallback for pre-generated pages in a site that is comprised almost entirely of user generated content. We’ll use a technique of optimistic URL routing where the 404 page is a serverless function to add serverless rendering on the fly.
Buzzwordy? Perhaps. Effective? Most certainly!
You can go and have a play with the demo site to help you imagine this use case. But only if you promise to come back.
Is that you? You came back? Great. Let’s dig in.
The idea behind this little example site is that it lets you create a nice, happy message and virtual pick-me-up to send to a friend. You can write a message, customize a lollipop (or a popsicle, for my American friends) and get a URL to share with your intended recipient. And just like that, you’ve brightened up their day. What’s not to love?
Traditionally, we’d build this site using some server-side scripting to handle the form submissions, add new lollies (our user generated content) to a database and generate a unique URL. Then we’d use some more server-side logic to parse requests for these pages, query the database to get the data needed to populate a page view, render it with a suitable template, and return it to the user.
That all seems logical.
Technical architects and tech leads often get this question when scoping a project. They need to plan, pay for, and provision enough horsepower in case of success.
This virtual lollipop site is no mere trinket. This thing is going to make me a gazillionaire due to all the positive messages we all want to send each other! Traffic levels are going to spike as the word gets out. I had better have a good strategy of ensuring that the servers can handle the hefty load. I might add some caching layers, some load balancers, and I’ll design my database and database servers to be able to share the load without groaning from the demand to make and serve all these lollies.
Except… I don’t know how to do that stuff.
And I don’t know how much it would cost to add that infrastructure and keep it all humming. It’s complicated.
This is why I love to simplify my hosting by pre-rendering as much as I can.
Serving static pages is significantly simpler and cheaper than serving pages dynamically from a web server which needs to perform some logic to generate views on demand for every visitor.
Since we are working with lots of user generated content, it still makes sense to use a database, but I’m not going to manage that myself. Instead, I’ll choose one of the many database options available as a service. And I’ll talk to it via its APIs.
I might choose Firebase, or MongoDB, or any number of others. Chris compiled a few of these on an excellent site about serverless resources which is well worth exploring.
In this case, I selected Fauna to use as my data store. Fauna has a nice API for stashing and querying data. It is a no-SQL flavored data store and gives me just what I need.
Critically, Fauna have made an entire business out of providing database services. They have the deep domain knowledge that I’ll never have. By using a database-as-a-service provider, I just inherited an expert data service team for my project, complete with high availability infrastructure, capacity and compliance peace of mind, skilled support engineers, and rich documentation.
Such are the advantages of using a third-party service like this rather than rolling your own.
I often find myself doodling the logical flow of things when I’m working on a proof of concept. Here’s my doodle for this site:
And a little explanation:
This kind of approach, which first assumes static/pre-generated assets, only then falling back to a dynamic render when a static view is not available was usefully described by Markus Schork of Unilever as “Static First” which I rather like.
You could just dive into the code for this site, which is open source and available for you to explore, or we could talk some more.
You want to dig in a little further, and explore the implementation of this example? OK, I’ll explain in some more details:
In a moment, we’ll talk about how we post data into the database, but first, let’s assume that there are some entries in the database already. We are going to want to generate a site which includes a page for each and every one of those.
Static site generators are great at this. They chomp through data, apply it to templates, and output HTML files ready to be served. We could use any generator for this example. I chose Eleventy due to it’s relative simplicity and the speed of its site generation.
To feed Eleventy some data, we have a number of options. One is to give it some JavaScript which returns structured data. This is perfect for querying a database API.
Our Eleventy data file will look something like this:
// Set up a connection with the Fauna database.
// Use an environment variable to authenticate
// and get access to the database.
const faunadb = require('faunadb');
const q = faunadb.query;
const client = new faunadb.Client({
secret: process.env.FAUNADB_SERVER_SECRET
});
module.exports = () => {
return new Promise((resolve, reject) => {
// get the most recent 100,000 entries (for the sake of our example)
client.query(
q.Paginate(q.Match(q.Ref("indexes/all_lollies")),{size:100000})
).then((response) => {
// get all data for each entry
const lollies = response.data;
const getAllDataQuery = lollies.map((ref) => {
return q.Get(ref);
});
return client.query(getAllDataQuery).then((ret) => {
// send the data back to Eleventy for use in the site build
resolve(ret);
});
}).catch((error) => {
console.log("error", error);
reject(error);
});
})
}
I named this file lollies.js
which will make all the data it returns available to Eleventy in a collection called lollies
.
We can now use that data in our templates. If you’d like to see the code which takes that and generates a page for each item, you can see it in the code repository.
When we create a new lolly page we need to capture user content in the database so that it can be used to populate a page at a given URL in the future. For this, we are using a traditional HTML form which posts data to a suitable form handler.
The form looks something like this (or see the full code in the repo):
<form name="new-lolly" action="/new" method="POST">
<!-- Default "flavors": 3 bands of colors with color pickers -->
<input type="color" id="flavourTop" name="flavourTop" value="#d52358" />
<input type="color" id="flavourMiddle" name="flavourMiddle" value="#e95946" />
<input type="color" id="flavourBottom" name="flavourBottom" value="#deaa43" />
<!-- Message fields -->
<label for="recipientName">To</label>
<input type="text" id="recipientName" name="recipientName" />
<label for="message">Say something nice</label>
<textarea name="message" id="message" cols="30" rows="10"></textarea>
<label for="sendersName">From</label>
<input type="text" id="sendersName" name="sendersName" />
<!-- A descriptive submit button -->
<input type="submit" value="Freeze this lolly and get a link">
</form>
We have no web servers in our hosting scenario, so we will need to devise somewhere to handle the HTTP posts being submitted from this form. This is a perfect use case for a serverless function. I’m using Netlify Functions for this. You could use Amazon Web Services, Lambda, Google Cloud, or Azure Functions if you prefer, but I like the simplicity of the workflow with Netlify Functions, and the fact that this will keep my serverless API and my UI all together in one code repository.
It is good practice to avoid leaking back-end implementation details into your front-end. A clear separation helps to keep things more portable and tidy. Take a look at the action
attribute of the form element above. It posts data to a path on my site called /new
which doesn’t really hint at what service this will be talking to.
We can use redirects to route that to any service we like. I’ll send it to a serverless function which I’ll be provisioning as part of this project, but it could easily be customized to send the data elsewhere if we wished. Netlify gives us a simple and highly optimized redirects engine which directs our traffic out at the CDN level, so users are very quickly routed to the correct place.
The redirect rule below (which lives in my project’s [netlify.toml](https://github.com/philhawksworth/virtual-lolly/blob/master/netlify.toml)
file) will proxy requests to /new
through to a serverless function hosted by Netlify Functions called [newLolly.js](https://github.com/philhawksworth/virtual-lolly/blob/master/src/functions/newLolly.js)
.
# resolve the "new" URL to a function
[[redirects]]
from = "/new"
to = "/.netlify/functions/newLolly"
status = 200
Let’s look at that serverless function which:
First, we’ll require the various utilities we’ll need to parse the form data, connect to the Fauna database and create readably short unique IDs for new lollies.
const faunadb = require('faunadb'); // For accessing FaunaDB
const shortid = require('shortid'); // Generate short unique URLs
const querystring = require('querystring'); // Help us parse the form data
// First we set up a new connection with our database.
// An environment variable helps us connect securely
// to the correct database.
const q = faunadb.query
const client = new faunadb.Client({
secret: process.env.FAUNADB_SERVER_SECRET
})
Now we’ll add some code to the handle requests to the serverless function. The handler function will parse the request to get the data we need from the form submission, then generate a unique ID for the new lolly, and then create it as a new record in the database.
// Handle requests to our serverless function
exports.handler = (event, context, callback) => {
// get the form data
const data = querystring.parse(event.body);
// add a unique path id. And make a note of it - we'll send the user to it later
const uniquePath = shortid.generate();
data.lollyPath = uniquePath;
// assemble the data ready to send to our database
const lolly = {
data: data
};
// Create the lolly entry in the fauna db
client.query(q.Create(q.Ref('classes/lollies'), lolly))
.then((response) => {
// Success! Redirect the user to the unique URL for this new lolly page
return callback(null, {
statusCode: 302,
headers: {
Location: `/lolly/${uniquePath}`,
}
});
}).catch((error) => {
console.log('error', error);
// Error! Return the error with statusCode 400
return callback(null, {
statusCode: 400,
body: JSON.stringify(error)
});
});
}
Let’s check our progress. We have a way to create new lolly pages in the database. And we’ve got an automated build which generates a page for every one of our lollies.
To ensure that there is a complete set of pre-generated pages for every lolly, we should trigger a rebuild whenever a new one is successfully added to the database. That is delightfully simple to do. Our build is already automated thanks to our static site generator. We just need a way to trigger it. With Netlify, we can define as many build hooks as we like. They are webhooks which will rebuild and deploy our site of they receive an HTTP POST request. Here’s the one I created in the site’s admin console in Netlify:
To regenerate the site, including a page for each lolly recorded in the database, we can make an HTTP POST request to this build hook as soon as we have saved our new data to the database.
This is the code to do that:
const axios = require('axios'); // Simplify making HTTP POST requests
// Trigger a new build to freeze this lolly forever
axios.post('https://api.netlify.com/build_hooks/5d46fa20da4a1b70XXXXXXXXX')
.then(function (response) {
// Report back in the serverless function's logs
console.log(response);
})
.catch(function (error) {
// Describe any errors in the serverless function's logs
console.log(error);
});
You can see it in context, added to the success handler for the database insertion in the full code.
This is all great if we are happy to wait for the build and deployment to complete before we share the URL of our new lolly with its intended recipient. But we are not a patient lot, and when we get that nice new URL for the lolly we just created, we’ll want to share it right away.
Sadly, if we hit that URL before the site has finished regenerating to include the new page, we’ll get a 404. But happily, we can use that 404 to our advantage.
With custom 404 routing, we can choose to send every failed request for a lolly page to a page which will can look for the lolly data directly in the database. We could do that in with client-side JavaScript if we wanted, but even better would be to generate a ready-to-view page dynamically from a serverless function.
Here’s how:
Firstly, we need to tell all those hopeful requests for a lolly page that come back empty to go instead to our serverless function. We do that with another rule in our Netlify redirects configuration:
# unfound lollies should proxy to the API directly
[[redirects]]
from = "/lolly/*"
to = "/.netlify/functions/showLolly?id=:splat"
status = 302
This rule will only be applied if the request for a lolly page did not find a static page ready to be served. It creates a temporary redirect (HTTP 302) to our serverless function, which looks something like this:
const faunadb = require('faunadb'); // For accessing FaunaDB
const pageTemplate = require('./lollyTemplate.js'); // A JS template litereal
// setup and auth the Fauna DB client
const q = faunadb.query;
const client = new faunadb.Client({
secret: process.env.FAUNADB_SERVER_SECRET
});
exports.handler = (event, context, callback) => {
// get the lolly ID from the request
const path = event.queryStringParameters.id.replace("/", "");
// find the lolly data in the DB
client.query(
q.Get(q.Match(q.Index("lolly_by_path"), path))
).then((response) => {
// if found return a view
return callback(null, {
statusCode: 200,
body: pageTemplate(response.data)
});
}).catch((error) => {
// not found or an error, send the sad user to the generic error page
console.log('Error:', error);
return callback(null, {
body: JSON.stringify(error),
statusCode: 301,
headers: {
Location: `/melted/index.html`,
}
});
});
}
If a request for any other page (not within the /lolly/
path of the site) should 404, we won’t send that request to our serverless function to check for a lolly. We can just send the user directly to a 404 page. Our [netlify.toml](https://github.com/philhawksworth/virtual-lolly/blob/master/netlify.toml)
config lets us define as many level of 404 routing as we’d like, by adding fallback rules further down in the file. The first successful match in the file will be honored.
# unfound lollies should proxy to the API directly
[[redirects]]
from = "/lolly/*"
to = "/.netlify/functions/showLolly?id=:splat"
status = 302
# Real 404s can just go directly here:
[[redirects]]
from = "/*"
to = "/melted/index.html"
status = 404
And we’re done! We’ve now got a site which is static first, and which will try to render content on the fly with a serverless function if a URL has not yet been generated as a static file.
Pretty snappy!
Our technique of triggering a build to regenerate the lollipop pages every single time a new entry is created might not be optimal forever. While it’s true that the automation of the build means it is trivial to redeploy the site, we might want to start throttling and optimizing things when we start to get very popular. (Which can only be a matter of time, right?)
That’s fine. Here are a couple of things to consider when we have very many pages to create, and more frequent additions to the database:
By combining both static, pre-generated assets, with serverless fallbacks which give dynamic rendering, we can satisfy a surprisingly broad set of use cases — all while avoiding the need to provision and maintain lots of dynamic infrastructure.
What other use cases might you be able to satisfy with this "static first” approach?
#javascript #serverless #web-service #microservices #web-development
1569318636
You might be seeing the term JAMstack popping up more and more frequently. I’ve been a fan of it as an approach for some time.
One of the principles of JAMstack is that of pre-rendering. In other words, it generates your site into a collection of static assets in advance, so that it can be served to your visitors with maximum speed and minimum overhead from a CDN or other optimized static hosting environment.
But if we are going to pre-generate our sites ahead of time, how do we make them feel dynamic? How do we build sites that need to change often? How do we work with things like user generated content?
As it happens, this can be a great use case for serverless functions. JAMstack and Serverless are the best of friends. They complement each other wonderfully.
In this article, we’ll look at a pattern of using serverless functions as a fallback for pre-generated pages in a site that is comprised almost entirely of user generated content. We’ll use a technique of optimistic URL routing where the 404 page is a serverless function to add serverless rendering on the fly.
Buzzwordy? Perhaps. Effective? Most certainly!
You can go and have a play with the demo site to help you imagine this use case. But only if you promise to come back.
Is that you? You came back? Great. Let’s dig in.
The idea behind this little example site is that it lets you create a nice, happy message and virtual pick-me-up to send to a friend. You can write a message, customize a lollipop (or a popsicle, for my American friends) and get a URL to share with your intended recipient. And just like that, you’ve brightened up their day. What’s not to love?
Traditionally, we’d build this site using some server-side scripting to handle the form submissions, add new lollies (our user generated content) to a database and generate a unique URL. Then we’d use some more server-side logic to parse requests for these pages, query the database to get the data needed to populate a page view, render it with a suitable template, and return it to the user.
That all seems logical.
Technical architects and tech leads often get this question when scoping a project. They need to plan, pay for, and provision enough horsepower in case of success.
This virtual lollipop site is no mere trinket. This thing is going to make me a gazillionaire due to all the positive messages we all want to send each other! Traffic levels are going to spike as the word gets out. I had better have a good strategy of ensuring that the servers can handle the hefty load. I might add some caching layers, some load balancers, and I’ll design my database and database servers to be able to share the load without groaning from the demand to make and serve all these lollies.
Except… I don’t know how to do that stuff.
And I don’t know how much it would cost to add that infrastructure and keep it all humming. It’s complicated.
This is why I love to simplify my hosting by pre-rendering as much as I can.
Serving static pages is significantly simpler and cheaper than serving pages dynamically from a web server which needs to perform some logic to generate views on demand for every visitor.
Since we are working with lots of user generated content, it still makes sense to use a database, but I’m not going to manage that myself. Instead, I’ll choose one of the many database options available as a service. And I’ll talk to it via its APIs.
I might choose Firebase, or MongoDB, or any number of others. Chris compiled a few of these on an excellent site about serverless resources which is well worth exploring.
In this case, I selected Fauna to use as my data store. Fauna has a nice API for stashing and querying data. It is a no-SQL flavored data store and gives me just what I need.
Critically, Fauna have made an entire business out of providing database services. They have the deep domain knowledge that I’ll never have. By using a database-as-a-service provider, I just inherited an expert data service team for my project, complete with high availability infrastructure, capacity and compliance peace of mind, skilled support engineers, and rich documentation.
Such are the advantages of using a third-party service like this rather than rolling your own.
I often find myself doodling the logical flow of things when I’m working on a proof of concept. Here’s my doodle for this site:
And a little explanation:
This kind of approach, which first assumes static/pre-generated assets, only then falling back to a dynamic render when a static view is not available was usefully described by Markus Schork of Unilever as “Static First” which I rather like.
You could just dive into the code for this site, which is open source and available for you to explore, or we could talk some more.
You want to dig in a little further, and explore the implementation of this example? OK, I’ll explain in some more details:
In a moment, we’ll talk about how we post data into the database, but first, let’s assume that there are some entries in the database already. We are going to want to generate a site which includes a page for each and every one of those.
Static site generators are great at this. They chomp through data, apply it to templates, and output HTML files ready to be served. We could use any generator for this example. I chose Eleventy due to it’s relative simplicity and the speed of its site generation.
To feed Eleventy some data, we have a number of options. One is to give it some JavaScript which returns structured data. This is perfect for querying a database API.
Our Eleventy data file will look something like this:
// Set up a connection with the Fauna database.
// Use an environment variable to authenticate
// and get access to the database.
const faunadb = require('faunadb');
const q = faunadb.query;
const client = new faunadb.Client({
secret: process.env.FAUNADB_SERVER_SECRET
});
module.exports = () => {
return new Promise((resolve, reject) => {
// get the most recent 100,000 entries (for the sake of our example)
client.query(
q.Paginate(q.Match(q.Ref("indexes/all_lollies")),{size:100000})
).then((response) => {
// get all data for each entry
const lollies = response.data;
const getAllDataQuery = lollies.map((ref) => {
return q.Get(ref);
});
return client.query(getAllDataQuery).then((ret) => {
// send the data back to Eleventy for use in the site build
resolve(ret);
});
}).catch((error) => {
console.log("error", error);
reject(error);
});
})
}
I named this file lollies.js
which will make all the data it returns available to Eleventy in a collection called lollies
.
We can now use that data in our templates. If you’d like to see the code which takes that and generates a page for each item, you can see it in the code repository.
When we create a new lolly page we need to capture user content in the database so that it can be used to populate a page at a given URL in the future. For this, we are using a traditional HTML form which posts data to a suitable form handler.
The form looks something like this (or see the full code in the repo):
<form name="new-lolly" action="/new" method="POST">
<!-- Default "flavors": 3 bands of colors with color pickers -->
<input type="color" id="flavourTop" name="flavourTop" value="#d52358" />
<input type="color" id="flavourMiddle" name="flavourMiddle" value="#e95946" />
<input type="color" id="flavourBottom" name="flavourBottom" value="#deaa43" />
<!-- Message fields -->
<label for="recipientName">To</label>
<input type="text" id="recipientName" name="recipientName" />
<label for="message">Say something nice</label>
<textarea name="message" id="message" cols="30" rows="10"></textarea>
<label for="sendersName">From</label>
<input type="text" id="sendersName" name="sendersName" />
<!-- A descriptive submit button -->
<input type="submit" value="Freeze this lolly and get a link">
</form>
We have no web servers in our hosting scenario, so we will need to devise somewhere to handle the HTTP posts being submitted from this form. This is a perfect use case for a serverless function. I’m using Netlify Functions for this. You could use Amazon Web Services, Lambda, Google Cloud, or Azure Functions if you prefer, but I like the simplicity of the workflow with Netlify Functions, and the fact that this will keep my serverless API and my UI all together in one code repository.
It is good practice to avoid leaking back-end implementation details into your front-end. A clear separation helps to keep things more portable and tidy. Take a look at the action
attribute of the form element above. It posts data to a path on my site called /new
which doesn’t really hint at what service this will be talking to.
We can use redirects to route that to any service we like. I’ll send it to a serverless function which I’ll be provisioning as part of this project, but it could easily be customized to send the data elsewhere if we wished. Netlify gives us a simple and highly optimized redirects engine which directs our traffic out at the CDN level, so users are very quickly routed to the correct place.
The redirect rule below (which lives in my project’s [netlify.toml](https://github.com/philhawksworth/virtual-lolly/blob/master/netlify.toml)
file) will proxy requests to /new
through to a serverless function hosted by Netlify Functions called [newLolly.js](https://github.com/philhawksworth/virtual-lolly/blob/master/src/functions/newLolly.js)
.
# resolve the "new" URL to a function
[[redirects]]
from = "/new"
to = "/.netlify/functions/newLolly"
status = 200
Let’s look at that serverless function which:
First, we’ll require the various utilities we’ll need to parse the form data, connect to the Fauna database and create readably short unique IDs for new lollies.
const faunadb = require('faunadb'); // For accessing FaunaDB
const shortid = require('shortid'); // Generate short unique URLs
const querystring = require('querystring'); // Help us parse the form data
// First we set up a new connection with our database.
// An environment variable helps us connect securely
// to the correct database.
const q = faunadb.query
const client = new faunadb.Client({
secret: process.env.FAUNADB_SERVER_SECRET
})
Now we’ll add some code to the handle requests to the serverless function. The handler function will parse the request to get the data we need from the form submission, then generate a unique ID for the new lolly, and then create it as a new record in the database.
// Handle requests to our serverless function
exports.handler = (event, context, callback) => {
// get the form data
const data = querystring.parse(event.body);
// add a unique path id. And make a note of it - we'll send the user to it later
const uniquePath = shortid.generate();
data.lollyPath = uniquePath;
// assemble the data ready to send to our database
const lolly = {
data: data
};
// Create the lolly entry in the fauna db
client.query(q.Create(q.Ref('classes/lollies'), lolly))
.then((response) => {
// Success! Redirect the user to the unique URL for this new lolly page
return callback(null, {
statusCode: 302,
headers: {
Location: `/lolly/${uniquePath}`,
}
});
}).catch((error) => {
console.log('error', error);
// Error! Return the error with statusCode 400
return callback(null, {
statusCode: 400,
body: JSON.stringify(error)
});
});
}
Let’s check our progress. We have a way to create new lolly pages in the database. And we’ve got an automated build which generates a page for every one of our lollies.
To ensure that there is a complete set of pre-generated pages for every lolly, we should trigger a rebuild whenever a new one is successfully added to the database. That is delightfully simple to do. Our build is already automated thanks to our static site generator. We just need a way to trigger it. With Netlify, we can define as many build hooks as we like. They are webhooks which will rebuild and deploy our site of they receive an HTTP POST request. Here’s the one I created in the site’s admin console in Netlify:
To regenerate the site, including a page for each lolly recorded in the database, we can make an HTTP POST request to this build hook as soon as we have saved our new data to the database.
This is the code to do that:
const axios = require('axios'); // Simplify making HTTP POST requests
// Trigger a new build to freeze this lolly forever
axios.post('https://api.netlify.com/build_hooks/5d46fa20da4a1b70XXXXXXXXX')
.then(function (response) {
// Report back in the serverless function's logs
console.log(response);
})
.catch(function (error) {
// Describe any errors in the serverless function's logs
console.log(error);
});
You can see it in context, added to the success handler for the database insertion in the full code.
This is all great if we are happy to wait for the build and deployment to complete before we share the URL of our new lolly with its intended recipient. But we are not a patient lot, and when we get that nice new URL for the lolly we just created, we’ll want to share it right away.
Sadly, if we hit that URL before the site has finished regenerating to include the new page, we’ll get a 404. But happily, we can use that 404 to our advantage.
With custom 404 routing, we can choose to send every failed request for a lolly page to a page which will can look for the lolly data directly in the database. We could do that in with client-side JavaScript if we wanted, but even better would be to generate a ready-to-view page dynamically from a serverless function.
Here’s how:
Firstly, we need to tell all those hopeful requests for a lolly page that come back empty to go instead to our serverless function. We do that with another rule in our Netlify redirects configuration:
# unfound lollies should proxy to the API directly
[[redirects]]
from = "/lolly/*"
to = "/.netlify/functions/showLolly?id=:splat"
status = 302
This rule will only be applied if the request for a lolly page did not find a static page ready to be served. It creates a temporary redirect (HTTP 302) to our serverless function, which looks something like this:
const faunadb = require('faunadb'); // For accessing FaunaDB
const pageTemplate = require('./lollyTemplate.js'); // A JS template litereal
// setup and auth the Fauna DB client
const q = faunadb.query;
const client = new faunadb.Client({
secret: process.env.FAUNADB_SERVER_SECRET
});
exports.handler = (event, context, callback) => {
// get the lolly ID from the request
const path = event.queryStringParameters.id.replace("/", "");
// find the lolly data in the DB
client.query(
q.Get(q.Match(q.Index("lolly_by_path"), path))
).then((response) => {
// if found return a view
return callback(null, {
statusCode: 200,
body: pageTemplate(response.data)
});
}).catch((error) => {
// not found or an error, send the sad user to the generic error page
console.log('Error:', error);
return callback(null, {
body: JSON.stringify(error),
statusCode: 301,
headers: {
Location: `/melted/index.html`,
}
});
});
}
If a request for any other page (not within the /lolly/
path of the site) should 404, we won’t send that request to our serverless function to check for a lolly. We can just send the user directly to a 404 page. Our [netlify.toml](https://github.com/philhawksworth/virtual-lolly/blob/master/netlify.toml)
config lets us define as many level of 404 routing as we’d like, by adding fallback rules further down in the file. The first successful match in the file will be honored.
# unfound lollies should proxy to the API directly
[[redirects]]
from = "/lolly/*"
to = "/.netlify/functions/showLolly?id=:splat"
status = 302
# Real 404s can just go directly here:
[[redirects]]
from = "/*"
to = "/melted/index.html"
status = 404
And we’re done! We’ve now got a site which is static first, and which will try to render content on the fly with a serverless function if a URL has not yet been generated as a static file.
Pretty snappy!
Our technique of triggering a build to regenerate the lollipop pages every single time a new entry is created might not be optimal forever. While it’s true that the automation of the build means it is trivial to redeploy the site, we might want to start throttling and optimizing things when we start to get very popular. (Which can only be a matter of time, right?)
That’s fine. Here are a couple of things to consider when we have very many pages to create, and more frequent additions to the database:
By combining both static, pre-generated assets, with serverless fallbacks which give dynamic rendering, we can satisfy a surprisingly broad set of use cases — all while avoiding the need to provision and maintain lots of dynamic infrastructure.
What other use cases might you be able to satisfy with this "static first” approach?
#javascript #serverless #web-service #microservices #web-development
1591340335
APA Referencing Generator
Many students use APA style as the key citation style in their assignment in university or college. Although, many people find it quite difficult to write the reference of the source. You ought to miss the names and dates of authors. Hence, APA referencing generator is important for reducing the burden of students. They can now feel quite easy to do the assignments on time.
The functioning of APA referencing generator
If you are struggling hard to write the APA referencing then you can take the help of APA referencing generator. It will create an excellent list. You are required to enter the information about the source. Just ensure that the text is credible and original. If you will copy references then it is a copyright violation.
You can use a referencing generator in just a click. It will generate the right references for all the sources. You are required to organize in alphabetical order. The generator will make sure that you will get good grades.
How to use APA referencing generator?
Select what is required to be cited such as journal, book, film, and others. You can choose the type of required citations list and enter all the required fields. The fields are dates, author name, title, editor name, and editions, name of publishers, chapter number, page numbers, and title of journals. You can click for reference to be generated and you will get the desired result.
Chicago Referencing Generator
Do you require the citation style? You can rely on Chicago Referencing Generator and will ensure that you will get the right citation in just a click. The generator is created to provide solutions to students to cite their research paper in Chicago style. It has proved to be the quickest and best citation generator on the market. The generator helps to sort the homework issues in few seconds. It also saves a lot of time and energy.
This tool helps researchers, professional writers, and students to manage and generate text citation essays. It will help to write Chicago style in a fast and easy way. It also provides details and directions for formatting and cites resources.
So, you must stop wasting the time and can go for Chicago Referencing Generator or APA referencing generator. These citation generators will help to solve the problem of citation issues. You can easily create citations by using endnotes and footnotes.
So, you can generate bibliographies, references, in-text citations, and title pages. These are fully automatic referencing style. You are just required to enter certain details about the citation and you will get the citation in the proper and required format.
So, if you are feeling any problem in doing assignment then you can take the help of assignment help.
If you require help for Assignment then livewebtutors is the right place for you. If you see our prices, you will observe that they are actually very affordable. Also, you can always expect a discount. Our team is capable and versatile enough to offer you exactly what you need, the best services for the prices you can afford.
read more:- Are you struggling to write a bibliography? Use Harvard referencing generator
#apa referencing generator #harvard referencing generator #chicago referencing generator #mla referencing generator #deakin referencing generator #oxford referencing generator
1611567681
In the past few years, especially after Amazon Web Services (AWS) introduced its Lambda platform, serverless architecture became the business realm’s buzzword. The increasing popularity of serverless applications saw market leaders like Netflix, Airbnb, Nike, etc., adopting the serverless architecture to handle their backend functions better. Moreover, serverless architecture’s market size is expected to reach a whopping $9.17 billion by the year 2023.
Global_Serverless_Architecture_Market_2019-2023
Why use serverless computing?
As a business it is best to approach a professional mobile app development company to build apps that are deployed on various servers; nevertheless, businesses should understand that the benefits of the serverless applications lie in the possibility it promises ideal business implementations and not in the hype created by cloud vendors. With the serverless architecture, the developers can easily code arbitrary codes on-demand without worrying about the underlying hardware.
But as is the case with all game-changing trends, many businesses opt for serverless applications just for the sake of being up-to-date with their peers without thinking about the actual need of their business.
The serverless applications work well with stateless use cases, the cases which execute cleanly and give the next operation in a sequence. On the other hand, the serverless architecture is not fit for predictable applications where there is a lot of reading and writing in the backend system.
Another benefit of working with the serverless software architecture is that the third-party service provider will charge based on the total number of requests. As the number of requests increases, the charge is bound to increase, but then it will cost significantly less than a dedicated IT infrastructure.
Defining serverless software architecture
In serverless software architecture, the application logic is implemented in an environment where operating systems, servers, or virtual machines are not visible. Although where the application logic is executed is running on any operating system which uses physical servers. But the difference here is that managing the infrastructure is the soul of the service provider and the mobile app developer focuses only on writing the codes.
There are two different approaches when it comes to serverless applications. They are
Backend as a service (BaaS)
Function as a service (FaaS)
Moreover, other examples of third-party services are Autho, AWS Cognito (authentication as a service), Amazon Kinesis, Keen IO (analytics as a service), and many more.
FaaS serverless architecture is majorly used with microservices architecture as it renders everything to the organization. AWS Lambda, Google Cloud functions, etc., are some of the examples of FaaS implementation.
Pros of Serverless applications
There are specific ways in which serverless applications can redefine the way business is done in the modern age and has some distinct advantages over the traditional could platforms. Here are a few –
🔹 Highly Scalable
The flexible nature of the serverless architecture makes it ideal for scaling the applications. The serverless application’s benefit is that it allows the vendor to run each of the functions in separate containers, allowing optimizing them automatically and effectively. Moreover, unlike in the traditional cloud, one doesn’t need to purchase a certain number of resources in serverless applications and can be as flexible as possible.
🔹 Cost-Effective
As the organizations don’t need to spend hundreds and thousands of dollars on hardware, they don’t need to pay anything to the engineers to maintain the hardware. The serverless application’s pricing model is execution based as the organization is charged according to the executions they have made.
The company that uses the serverless applications is allotted a specific amount of time, and the pricing of the execution depends on the memory required. Different types of costs like presence detection, access authorization, image processing, etc., associated with a physical or virtual server is completely eliminated with the serverless applications.
🔹 Focuses on user experience
As the companies don’t always think about maintaining the servers, it allows them to focus on more productive things like developing and improving customer service features. A recent survey says that about 56% of the users are either using or planning to use the serverless applications in the coming six months.
Moreover, as the companies would save money with serverless apps as they don’t have to maintain any hardware system, it can be then utilized to enhance the level of customer service and features of the apps.
🔹 Ease of migration
It is easy to get started with serverless applications by porting individual features and operate them as on-demand events. For example, in a CMS, a video plugin requires transcoding video for different formats and bitrates. If the organization wished to do this with a WordPress server, it might not be a good fit as it would require resources dedicated to serving pages rather than encoding the video.
Moreover, the benefits of serverless applications can be used optimally to handle metadata encoding and creation. Similarly, serverless apps can be used in other plugins that are often prone to critical vulnerabilities.
Cons of serverless applications
Despite having some clear benefits, serverless applications are not specific for every single use case. We have listed the top things that an organization should keep in mind while opting for serverless applications.
🔹 Complete dependence on third-party vendor
In the realm of serverless applications, the third-party vendor is the king, and the organizations have no options but to play according to their rules. For example, if an application is set in Lambda, it is not easy to port it into Azure. The same is the case for coding languages. In present times, only Python developers and Node.js developers have the luxury to choose between existing serverless options.
Therefore, if you are planning to consider serverless applications for your next project, make sure that your vendor has everything needed to complete the project.
🔹 Challenges in debugging with traditional tools
It isn’t easy to perform debugging, especially for large enterprise applications that include various individual functions. Serverless applications use traditional tools and thus provide no option to attach a debugger in the public cloud. The organization can either do the debugging process locally or use logging for the same purpose. In addition to this, the DevOps tools in the serverless application do not support the idea of quickly deploying small bits of codes into running applications.
#serverless-application #serverless #serverless-computing #serverless-architeture #serverless-application-prosand-cons
1602681082
By this point most enterprises, including those running on legacy infrastructures, are familiar with the benefits of serverless computing:
The benefits of agility and cost reduction are especially relevant in the current macroeconomic environment when customer behavior is changing, end-user needs are difficult to predict, and development teams are under pressure to do more with less.
So serverless is a no-brainer, right?
Not exactly. Serverless might be relatively painless for a new generation of cloud-native software companies that grew up in a world of APIs and microservices, but it creates headaches for the many organizations that still rely heavily on legacy infrastructure.
In particular, enterprises running mainframe CICS programs are likely to encounter frustrating stumbling blocks on the path to launching Functions as a Service (FaaS). This population includes global enterprises that depend on CICS applications to effectively manage high-volume transactional processing requirements – particularly in the banking, financial services, and insurance industries.
These organizations stand to achieve time and cost savings through a modern approach to managing legacy infrastructure, as opposed to launching serverless applications on a brittle foundation. Here are three of the biggest obstacles they face and how to overcome them.
Middleware that introduces complexity, technical debt, and latency. Many organizations looking to integrate CICS applications into a microservices or serverless architecture rely on middleware (e.g., an ESB or SOA) to access data from the underlying applications. This strategy introduces significant runtime performance challenges and creates what one bank’s chief architect referred to as a “lasagna architecture,” making DevOps impossible.
#serverless architecture #serverless functions #serverless benefits #mainframes #serverless api #serverless integration
1620992479
In this digital world, online businesses aspire to catch the attention of users in a modern and smarter way. To achieve it, they need to traverse through new approaches. Here comes to spotlight is the user-generated content or UGC.
What is user-generated content?
“ It is the content by users for users.”
Generally, the UGC is the unbiased content created and published by the brand users, social media followers, fans, and influencers that highlight their experiences with the products or services. User-generated content has superseded other marketing trends and fallen into the advertising feeds of brands. Today, more than 86 percent of companies use user-generated content as part of their marketing strategy.
In this article, we have explained the ten best ideas to create wonderful user-generated content for your brand. Let’s start without any further ado.
Generally, social media platforms help the brand to generate content for your users. Any user content that promotes your brand on the social media platform is the user-generated content for your business. When users create and share content on social media, they get 28% higher engagement than a standard company post.
Furthermore, you can embed your social media feed on your website also. you can use the Social Stream Designer WordPress plugin that will integrate various social media feeds from different social media platforms like Facebook, Twitter, Instagram, and many more. With this plugin, you can create a responsive wall on your WordPress website or blog in a few minutes. In addition to this, the plugin also provides more than 40 customization options to make your social stream feeds more attractive.
In general, surveys can be used to figure out attitudes, reactions, to evaluate customer satisfaction, estimate their opinions about different problems. Another benefit of customer surveys is that collecting outcomes can be quick. Within a few minutes, you can design and load a customer feedback survey and send it to your customers for their response. From the customer survey data, you can find your strengths, weaknesses, and get the right way to improve them to gain more customers.
Additionally, it is the best way to convert your brand leads to valuable customers. The key to running a successful contest is to make sure that the reward is fair enough to motivate your participation. If the product is relevant to your participant, then chances are they were looking for it in the first place, and giving it to them for free just made you move forward ahead of your competitors. They will most likely purchase more if your product or service satisfies them.
Furthermore, running contests also improve the customer-brand relationship and allows more people to participate in it. It will drive a real result for your online business. If your WordPress website has Google Analytics, then track contest page visits, referral traffic, other website traffic, and many more.
The business reviews help your consumers to make a buying decision without any hurdle. While you may decide to remove all the negative reviews about your business, those are still valuable user-generated content that provides honest opinions from real users. Customer feedback can help you with what needs to be improved with your products or services. This thing is not only beneficial to the next customer but your business as a whole.
Reviews are powerful as the platform they are built upon. That is the reason it is important to gather reviews from third-party review websites like Google review, Facebook review, and many more, or direct reviews on a website. It is the most vital form of feedback that can help brands grow globally and motivate audience interactions.
However, you can also invite your customers to share their unique or successful testimonials. It is a great way to display your products while inspiring others to purchase from your website.
Moreover, Instagram videos create around 3x more comments rather than Instagram photo posts. Instagram videos generally include short videos posted by real customers on Instagram with the tag of a particular brand. Brands can repost the stories as user-generated content to engage more audiences and create valid promotions on social media.
Similarly, imagine you are browsing a YouTube channel, and you look at a brand being supported by some authentic customers through a small video. So, it will catch your attention. With the videos, they can tell you about the branded products, especially the unboxing videos displaying all the inside products and how well it works for them. That type of video is enough to create a sense of desire in the consumers.
#how to get more user generated content #importance of user generated content #user generated content #user generated content advantages #user generated content best practices #user generated content pros and cons