Visual Test Analytics – The Future of Software Test Reports

If you are a practitioner of automated testing, It's quite common to frequently script and runs a high number of automated tests for the businesses we work with.

 So when you have a high volume of test results to analyze, it can be challenging to analyze and understand the product's insights. Even exporting results in Excel will not help as such large amounts of data makes it difficult to identify trends.

Understanding API Rate-Limiting Techniques in Zato

Enabling rate-limiting in Zato means that access to Zato-based APIs can be throttled per endpoint, user, or service — including options to make limits apply to specific IP addresses only — and if limits are exceeded within a selected period of time, the invocation will fail. Let's check how to use it all.

Where and When Limits Apply

Rate-limiting aware objects in Zato

AWS Cloud Monitoring: Best Practices and Top-Notch Tools

The practicality and viability of AWS in the world of cloud computing can’t be overlooked. At present, it’s the trailblazer of cloud computing and currently rules over the 31% market share.

The AWS cloud computing services are nothing but quality-driven. They are future-driven and play a vital role in a business’s growth. But, first thing first, let’s why out why AWS cloud monitoring is essential.

WordPress Community Team Discusses Return to In-Person Events

Although the promise of effective COVID-19 vaccines is shining a light at the end of a long tunnel, the world remains firmly in the virus’ grip until distribution can ramp up to cover at-risk groups as well as the general populace.

As pandemic-weary communities muster the discipline to ride out the next few months under continued restrictions, a new discussion popped up on WordPress.org regarding the return to in-person events. WordPress has canceled all in-person events through the end of the year and 2021 flagship events have already been designated as online-only. Community organizer Angela Jin cited recent successful vaccine trials as a prompt for discussing how WordPress can safely resume in-person events:

There has been promising news around some successful trials for vaccines recently! As such, it seems worthwhile to discuss how the WordPress community can return to hosting safe, in-person events. 

Any in-person event would certainly be subject to local laws and any restrictions on gatherings, as they’ve always been. Beyond what local health authorities require, the Global Community Team may need to to help organizers identify what additional precautions are necessary to ensure in-person events are safe for participants. 

Jin offered several examples of “additional precautions” to ensure events are safe, such as mandatory masks, social distancing, outdoor events, limits on the number of attendees, and no food or drink service.

Although countries like Australia, Taiwan, and New Zealand, seem to have adequately contained the virus, the U.S., Europe, India, and Russia have cases spiraling out of control. The discussion seems oddly timed, as this week the U.S., which is leading the world in deaths, has seen daily deaths climb to 2,804, surpassing the previous record of 2,607 reported on April 15, during the first wave of the pandemic.

Several of those commenting mentioned that the discussion opener neglects a critical detail about whether or not in-person events would resume before vaccines are widely distributed.

“I’m surprised I don’t see mention of the vaccine being a requirement,” Mika Epstein said. “I could assume so, but the risk of COVID is human life.

“That means that unless WordPress (or any public event) has a way to ensure that no one will contract (and die) of COVID, then they have no business having any event, indoor or outdoor.

“Not every country is handling things equally well, and just in the US alone, there are many places where the law says ‘do not have events’ but the local authorities refuse to intercede, which resulted in 80% of the people attending an outdoor party not too far from me all testing positive.”

WordPress is a global community and reliance on local laws may still put event attendees at risk in communities that have been subject to a failure of leadership in protecting citizens.

Cami Kaos, an eight-year WordPress community organizer, echoed these thoughts, saying, “The one thing we need to have in place in order to make a safe re-entry into in person events is to have wide spread access to an effective vaccine.” She commented on the difficulties of trying to ensure attendees don’t inadvertently put each other at risk:

It’s all well and good for us to say you can only organize within the recommendations of your local community, but we have no way of knowing how responsible individuals are being. Of knowing if they have come in from out of town for the event. If a member of their household is a frontline worker who might be exposed daily, if someone in their family is high risk and we could be endangering a life.

Without widely distributed vaccines, hosting in-person gatherings with the possibility of attendees traveling from hotspot locations would be unconscionable.

Kaos also commented on how difficult enforcement would be for WordPress community volunteers who would be tasked with making sure individuals wear masks properly, use hand sanitizer, maintain distance, and uphold any other requirements.

“All of this would be putting unpaid and uncompensated volunteers at risk unnecessarily,” Kaos said.

“If people would like to make the choice to see their friends and collaborators in person, that can be their choice. But I don’t feel morally comfortable legally and finically supporting in-person gatherings when I think we could prevent even one death by extending our pause on in-person events to wait for a vaccine to be readily available.”

Other commenters discussed how to manage the logistics of sponsoring masks and sanitizer for organizers by coordinating with local venues and figuring out a way around slow international shipments.

“This actually opens totally new ways to organize WordPress events!” WordCamp organizer Timi Wahalahti said. “Why not have a bicycle trip or something similar with your WordPress friends?”

Live event recordings are another consideration for hosting events in a way that is accessible to more vulnerable populations. According to WordPress community organizer Andrea Middleton, professional video recording has historically been cost prohibitive at scale.

“A year ago focusing on recordings may have sounded in some ways counterproductive to growing in-person events,” WordPress core contributor David Ryan said. “But I think today they provide a short-term fix to the head count crunch, can help bring/keep folx in-the-fold while making in-person attendance even safer, all while adding long-term value even when travel and gatherings normalize.”

The discussion on finding a safe path forward for restarting in-person events will be open until December 16, 2020. Organizers and community members can comment on the post for consideration. Angela Jin said the Community Team will continue to support online events in 2021 and beyond, regardless of any decisions resulting from the discussion.

Spamhaus Technology Launches Threat Intelligence API Beta

Spamhaus Technology Ltd has recently announced the release of its Intelligence API Beta. This is the first time Spamhaus has released its extensive threat intelligence via API, providing enriched data relating to IP addresses exhibiting compromised behavior.  

Available free of charge, developers can readily access enhanced data that catalogues IP addresses compromised by malware, worms, Trojan infections, devices controlled by botnets, and third party exploits, such as open proxies.

Happier HTML5 form validation in Vue

It’s kind of neat that we can do input:invalid {} in CSS to style an input when it’s in an invalid state. Yet, used exactly like that, the UX is pretty bad. Say you have <input type="text" required>. That’s immediately invalid before the user has done anything. That’s such a bummer UX that you never see it used in the wild. But if we could just avoid that one thing, that :invalid selector can do a ton of work for us in form validation without needing to lean on a big fancy library.

Dave has an idea that’s a variation on the original 2017 idea.

It’s basically:

form.errors :invalid {
  outline: 2px solid red;
}

Now you’re only conditionally applying those native error styles when you’ve determined the form to be in an error state and added a class. And fortunately, testing that is pretty easy too. We could apply that class when the submit button is clicked:

submitButton.addEventListener("click", (e) => {
  form.classList.toggle("errors", !form.checkValidity())
});

Or you could do it when an input blurs or something. You could even wrap each input set in a wrapper and toggle the class on the wrapper when appropriate. The commented out code here could get you going there…

Dave kicked this idea over to Vue:

We initialize the form component with errors: false because we don’t want the error styling until the user has submitted the form. The invalidateForm function just sets this.error = true. That’s one problem with the CSS :invalid pseudo class, it’s way too eager. Hooking into the invalid events, delays the styling until after the first form submission attempt and we know the form has errors.

Not using any library (on top of what you already use) is pretty sweet. HTML form validation is pretty much there. Here’s a fork of Dave’s where error messaging is revealed as well:

Direct Link to ArticlePermalink


The post Happier HTML5 form validation in Vue appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

How to create a client-serverless Jamstack app using Netlify, Gatsby and Fauna

The Jamstack is a modern web development architecture based on client-side JavaScript, reusable APIs, and prebuilt Markup.

The key aspects of a Jamstack application are the following:

  • The entire app runs on a CDN (or ADN). CDN stands for Content Delivery Network and an ADN is an Application Delivery Network.
  • Everything lives in Git.
  • Automated builds run with a workflow when developers push the code.
  • There’s Automatic deployment of the prebuilt markup to the CDN/ADN.
  • Reusable APIs make hasslefree integrations with many of the services. To take a few examples, Stripe for the payment and checkout, Mailgun for email services, etc. We can also write custom APIs targeted to a specific use-case. We will see such examples of custom APIs in this article.
  • It’s practically Serverless. To put it more clearly, we do not maintain any servers, rather make use of already existing services (like email, media, database, search, and so on) or serverless functions.

In this article, we will learn how to build a Jamstack application that has:

  • A global data store with GraphQL support to store and fetch data with ease. We will use Fauna to accomplish this.
  • Serverless functions that also act as the APIs to fetch data from the Fauna data store. We will use Netlify serverless functions for this.
  • We will build the client side of the app using a Static Site Generator called Gatsbyjs.
  • Finally we will deploy the app on a CDN configured and managed by Netlify CDN.

So, what are we building today?

We all love shopping. How cool would it be to manage all of our shopping notes in a centralized place? So we’ll be building an app called ‘shopnote’ that allows us to manage shop notes. We can also add one or more items to a note, mark them as done, mark them as urgent, etc.

At the end of this article, our shopnote app will look like this,

TL;DR

We will learn things with a step-by-step approach in this article. If you want to jump into the source code or demonstration sooner, here are links to them.

Set up Fauna

Fauna is the data API for client-serverless applications. If you are familiar with any traditional RDBMS, a major difference with Fauna would be, it is a relational NOSQL system that gives all the capabilities of the legacy RDBMS. It is very flexible without compromising scalability and performance.

Fauna supports multiple APIs for data-access,

  • GraphQL: An open source data query and manipulation language. If you are new to the GraphQL, you can find more details from here, https://graphql.org/
  • Fauna Query Language (FQL): An API for querying Fauna. FQL has language specific drivers which makes it flexible to use with languages like JavaScript, Java, Go, etc. Find more details of FQL from here.

In this article we will explain the usages of GraphQL for the ShopNote application.

First thing first, sign up using this URL. Please select the free plan which is with a generous daily usage quota and more than enough for our usage.

Next, create a database by providing a database name of your choice. I have used shopnotes as the database name.

After creating the database, we will be defining the GraphQL schema and importing it into the database. A GraphQL schema defines the structure of the data. It defines the data types and the relationship between them. With schema we can also specify what kind of queries are allowed.

At this stage, let us create our project folder. Create a project folder somewhere on your hard drive with the name, shopnote. Create a file with the name, shopnotes.gql with the following content:

type ShopNote {
  name: String!
  description: String
  updatedAt: Time
  items: [Item!] @relation
}
 
type Item {
  name: String!
  urgent: Boolean
  checked: Boolean
  note: ShopNote!
}
 
type Query {
  allShopNotes: [ShopNote!]!
}

Here we have defined the schema for a shopnote list and item, where each ShopNote contains name, description, update time and a list of Items. Each Item type has properties like, name, urgent, checked and which shopnote it belongs to. 

Note the @relation directive here. You can annotate a field with the @relation directive to mark it for participating in a bi-directional relationship with the target type. In this case, ShopNote and Item are in a one-to-many relationship. It means, one ShopNote can have multiple Items, where each Item can be related to a maximum of one ShopNote.

You can read more about the @relation directive from here. More on the GraphQL relations can be found from here.

As a next step, upload the shopnotes.gql file from the Fauna dashboard using the IMPORT SCHEMA button,

Upon importing a GraphQL Schema, FaunaDB will automatically create, maintain, and update, the following resources:

  • Collections for each non-native GraphQL Type; in this case, ShopNote and Item.
  • Basic CRUD Queries/Mutations for each Collection created by the Schema, e.g. createShopNote allShopNotes; each of which are powered by FQL.
  • For specific GraphQL directives: custom Indexes or FQL for establishing relationships (i.e. @relation), uniqueness (@unique), and more!

Behind the scene, Fauna will also help to create the documents automatically. We will see that in a while.

Fauna supports a schema-free object relational data model. A database in Fauna may contain a group of collections. A collection may contain one or more documents. Each of the data records are inserted into the document. This forms a hierarchy which can be visualized as:

Here the data record can be arrays, objects, or of any other supported types. With the Fauna data model we can create indexes, enforce constraints. Fauna indexes can combine data from multiple collections and are capable of performing computations. 

At this stage, Fauna already created a couple of collections for us, ShopNote and Item. As we start inserting records, we will see the Documents are also getting created. We will be able view and query the records and utilize the power of indexes. You may see the data model structure appearing in your Fauna dashboard like this in a while,

Point to note here, each of the documents is identified by the unique ref attribute. There is also a ts field which returns the timestamp of the recent modification to the document. The data record is part of the data field. This understanding is really important when you interact with collections, documents, records using FQL built-in functions. However, in this article we will interact with them using GraphQL queries with Netlify Functions.

With all these understanding, let us start using our Shopenotes database that is created successfully and ready for use. 

Let us try some queries

Even though we have imported the schema and underlying things are in place, we do not have a document yet. Let us create one. To do that, copy the following GraphQL mutation query to the left panel of the GraphQL playground screen and execute.

mutation {
  createShopNote(data: {
    name: "My Shopping List"
    description: "This is my today's list to buy from Tom's shop"
    items: {
      create: [
        { name: "Butther - 1 pk", urgent: true }
        { name: "Milk - 2 ltrs", urgent: false }
        { name: "Meat - 1lb", urgent: false }
      ]
    }
  }) {
    _id
    name
    description
    items {
      data {
        name,
        urgent
      }
    }
  }
}

Note, as Fauna already created the GraphQL mutation classes in the background, we can directly use it like, createShopNote. Once successfully executed, you can see the response of a ShopNote creation at the right side of the editor.

The newly created ShopNote document has all the required details we have passed while creating it. We have seen ShopNote has a one-to-many relation with Item. You can see the shopnote response has the item data nested within it. In this case, one shopnote has three items. This is really powerful. Once the schema and relation are defined, the document will be created automatically keeping that relation in mind.

Now, let us try fetching all the shopnotes. Here is the GraphQL query:

query {
    allShopNotes {
    data {
      _id
      name
      description
      updatedAt
      items {
        data {
          name,
          checked,
          urgent
        }
      }
    }
  }
}

Let’s try the query in the playground as before:

Now we have a database with a schema and it is fully operational with creating and fetch functionality. Similarly, we can create queries for adding, updating, removing items to a shopnote and also updating and deleting a shopnote. These queries will be used at a later point in time when we create the serverless functions.

If you are interested to run other queries in the GraphQL editor, you can find them from here,

Create a Server Secret Key

Next, we need to create a secured server key to make sure the access to the database is authenticated and authorized.

Click on the SECURITY option available in the FaunaDB interface to create the key, like so,

On successful creation of the key, you will be able to view the key’s secret. Make sure to copy and save it somewhere safe.

We do not want anyone else to know about this key. It is not even a good idea to commit it to the source code repository. To maintain this secrecy, create an empty file called .env at the root level of your project folder.

Edit the .env file and add the following line to it (paste the generated server key in the place of, <YOUR_FAUNA_KEY_SECRET>).

FAUNA_SERVER_SECRET=<YOUR_FAUNA_KEY_SECRET>

Add a .gitignore file and write the following content to it. This is to make sure we do not commit the .env file to the source code repo accidentally. We are also ignoring node_modules as a best practice.

.env

We are done with all that had to do with Fauna’s setup. Let us move to the next phase to create serverless functions and APIs to access data from the Fauna data store. At this stage, the directory structure may look like this,

Set up Netlify Serverless Functions

Netlify is a great platform to create hassle-free serverless functions. These functions can interact with databases, file-system, and in-memory objects.

Netlify functions are powered by AWS Lambda. Setting up AWS Lambdas on our own can be a fairly complex job. With Netlify, we will simply set a folder and drop our functions. Writing simple functions automatically becomes APIs. 

First, create an account with Netlify. This is free and just like the FaunaDB free tier, Netlify is also very flexible.

Now we need to install a few dependencies using either npm or yarn. Make sure you have nodejs installed. Open a command prompt at the root of the project folder. Use the following command to initialize the project with node dependencies,

npm init -y

Install the netlify-cli utility so that we can run the serverless function locally.

npm install netlify-cli -g

Now we will install two important libraries, axios and dotenv. axios will be used for making the HTTP calls and dotenv will help to load the FAUNA_SERVER_SECRET environment variable from the .env file into process.env.

yarn add axios dotenv

Or:

npm i axios dotenv

Create serverless functions

Create a folder with the name, functions at the root of the project folder. We are going to keep all serverless functions under it.

Now create a subfolder called utils under the functions folder. Create a file called query.js under the utils folder. We will need some common code to query the data store for all the serverless functions. The common code will be in the query.js file.

First we import the axios library functionality and load the .env file. Next, we export an async function that takes the query and variables. Inside the async function, we make calls using axios with the secret key. Finally, we return the response.

// query.js
 
const axios = require("axios");
require("dotenv").config();
 
module.exports = async (query, variables) => {
  const result = await axios({
      url: "https://graphql.fauna.com/graphql",
      method: "POST",
      headers: {
          Authorization: `Bearer ${process.env.FAUNA_SERVER_SECRET}`
      },
      data: {
        query,
        variables
      }
 });
 
 return result.data;
};

Create a file with the name, get-shopnotes.js under the functions folder. We will perform a query to fetch all the shop notes.

// get-shopnotes.js
 
const query = require("./utils/query");
 
const GET_SHOPNOTES = `
   query {
       allShopNotes {
       data {
         _id
         name
         description
         updatedAt
         items {
           data {
             _id,
             name,
             checked,
             urgent
         }
       }
     }
   }
 }  
`;
 
exports.handler = async () => {
  const { data, errors } = await query(GET_SHOPNOTES);
 
  if (errors) {
    return {
      statusCode: 500,
      body: JSON.stringify(errors)
    };
  }
 
  return {
    statusCode: 200,
    body: JSON.stringify({ shopnotes: data.allShopNotes.data })
  };
};

Time to test the serverless function like an API. We need to do a one time setup here. Open a command prompt at the root of the project folder and type:

netlify login

This will open a browser tab and ask you to login and authorize access to your Netlify account. Please click on the Authorize button.

Next, create a file called, netlify.toml at the root of your project folder and add this content to it,

[build]
    functions = "functions"
 
[[redirects]]
   from = "/api/*"
   to = "/.netlify/functions/:splat"
   status = 200

This is to tell Netlify about the location of the functions we have written so that it is known at the build time.

Netlify automatically provides the APIs for the functions. The URL to access the API is in this form, /.netlify/functions/get-shopnotes which may not be very user-friendly. We have written a redirect to make it like, /api/get-shopnotes.

Ok, we are done. Now in command prompt type,

netlify dev

By default the app will run on localhost:8888 to access the serverless function as an API.

Open a browser tab and try this URL, http://localhost:8888/api/get-shopnotes:

Congratulations!!! You have got your first serverless function up and running.

Let us now write the next serverless function to create a ShopNote. This is going to be simple. Create a file named, create-shopnote.js under the functions folder. We need to write a mutation by passing the required parameters. 

//create-shopnote.js
 
const query = require("./utils/query");
 
const CREATE_SHOPNOTE = `
  mutation($name: String!, $description: String!, $updatedAt: Time!, $items: ShopNoteItemsRelation!) {
    createShopNote(data: {name: $name, description: $description, updatedAt: $updatedAt, items: $items}) {
      _id
      name
      description
      updatedAt
      items {
        data {
          name,
          checked,
          urgent
        }
      }
    }
  }
`;
 
exports.handler = async event => {
  
  const { name, items } = JSON.parse(event.body);
  const { data, errors } = await query(
    CREATE_SHOPNOTE, { name, items });
 
  if (errors) {
    return {
      statusCode: 500,
      body: JSON.stringify(errors)
    };
  }
 
  return {
    statusCode: 200,
    body: JSON.stringify({ shopnote: data.createShopNote })
  };
};

Please give your attention to the parameter, ShopNotesItemRelation. As we had created a relation between the ShopNote and Item in our schema, we need to maintain that while writing the query as well.

We have de-structured the payload to get the required information from the payload. Once we got those, we just called the query method to create a ShopNote.

Alright, let’s test it out. You can use postman or any other tools of your choice to test it like an API. Here is the screenshot from postman.

Great, we can create a ShopNote with all the items we want to buy from a shopping mart. What if we want to add an item to an existing ShopNote? Let us create an API for it. With the knowledge we have so far, it is going to be really quick.

Remember, ShopNote and Item are related? So to create an item, we have to mandatorily tell which ShopNote it is going to be part of. Here is our next serverless function to add an item to an existing ShopNote.

//add-item.js
 
const query = require("./utils/query");
 
const ADD_ITEM = `
  mutation($name: String!, $urgent: Boolean!, $checked: Boolean!, $note: ItemNoteRelation!) {
    createItem(data: {name: $name, urgent: $urgent, checked: $checked, note: $note}) {
      _id
      name
      urgent
      checked
      note {
        name
      }
    }
  }
`;
 
exports.handler = async event => {
  
  const { name, urgent, checked, note} = JSON.parse(event.body);
  const { data, errors } = await query(
    ADD_ITEM, { name, urgent, checked, note });
 
  if (errors) {
    return {
      statusCode: 500,
      body: JSON.stringify(errors)
    };
  }
 
  return {
    statusCode: 200,
    body: JSON.stringify({ item: data.createItem })
  };
};

We are passing the item properties like, name, if it is urgent, the check value and the note the items should be part of. Let’s see how this API can be called using postman,

As you see, we are passing the id of the note while creating an item for it.

We won’t bother writing the rest of the API capabilities in this article,  like updating, deleting a shop note, updating, deleting items, etc. In case, you are interested, you can look into those functions from the GitHub Repository.

However, after creating the rest of the API, you should have a directory structure like this,

We have successfully created a data store with Fauna, set it up for use, created an API backed by serverless functions, using Netlify Functions, and tested those functions/routes.

Congratulations, you did it. Next, let us build some user interfaces to show the shop notes and add items to it. To do that, we will use Gatsby.js (aka, Gatsby) which is a super cool, React-based static site generator.

The following section requires you to have basic knowledge of ReactJS. If you are new to it, you can learn it from here. If you are familiar with any other user interface technologies like, Angular, Vue, etc feel free to skip the next section and build your own using the APIs explained so far.

Set up the User Interfaces using Gatsby

We can set up a Gatsby project either using the starter projects or initialize it manually. We will build things from scratch to understand it better.

Install gatsby-cli globally. 

npm install -g gatsby-cli

Install gatsby, react and react-dom

yarn add gatsby react react-dom

Edit the scripts section of the package.json file to add a script for develop.

"scripts": {
  "develop": "gatsby develop"
 }

Gatsby projects need a special configuration file called, gatsby-config.js. Please create a file named, gatsby-config.js at the root of the project folder with the following content,

module.exports = {
  // keep it empty    
}

Let’s create our first page with Gatsby. Create a folder named, src at the root of the project folder. Create a subfolder named pages under src. Create a file named, index.js under src/pages with the following content:

import React, { useEffect, useState } from 'react';    
 
export default () => {    
  const [loading, setLoading ] = useState(false);    
  const [shopnotes, setShopnotes] = useState(null);    
 
  return (
    <>    
      <h1>Shopnotes to load here...</h1>
    </>        
  )    
}

Let’s run it. We generally need to use the command gatsby develop to run the app locally. As we have to run the client side application with netlify functions, we will continue to use, netlify dev command.

netlify dev

That’s all. Try accessing the page at http://localhost:8888. You should see something like this,

Gatsby project build creates a couple of output folders which you may not want to push to the source code repository. Let us add a few entries to the .gitignore file so that we do not get unwanted noise.

Add .cache, node_modules and public to the .gitignore file. Here is the full content of the file:

.cache
public
node_modules
*.env

At this stage, your project directory structure should match with the following:

Thinking of the UI components

We will create small logical components to achieve the ShopNote user interface. The components are:

  • Header: A header component consists of the Logo, heading and the create button to create a shopnote.
  • Shopenotes: This component will contain the list of the shop note (Note component).
  • Note: This is individual notes. Each of the notes will contain one or more items.
  • Item: Each of the items. It consists of the item name and actions to add, remove, edit an item.

You can see the sections marked in the picture below:

Install a few more dependencies

We will install a few more dependencies required for the user interfaces to be functional and look better. Open a command prompt at the root of the project folder and install these dependencies,

yarn add bootstrap lodash moment react-bootstrap react-feather shortid

Lets load all the Shop Notes

We will use the Reactjs useEffect hook to make the API call and update the shopnotes state variables. Here is the code to fetch all the shop notes. 

useEffect(() => {
  axios("/api/get-shopnotes").then(result => {
    if (result.status !== 200) {
      console.error("Error loading shopnotes");
      console.error(result);
      return;
    }
    setShopnotes(result.data.shopnotes);
    setLoading(true);
  });
}, [loading]);

Finally, let us change the return section to use the shopnotes data. Here we are checking if the data is loaded. If so, render the Shopnotes component by passing the data we have received using the API.

return (
  <div className="main">
    <Header />
    {
      loading ? <Shopnotes data = { shopnotes } /> : <h1>Loading...</h1>
    }
  </div>
); 

You can find the entire index.js file code from here The index.js file creates the initial route(/) for the user interface. It uses other components like, Shopnotes, Note and Item to make the UI fully operational. We will not go to a great length to understand each of these UI components. You can create a folder called components under the src folder and copy the component files from here.

Finally, the index.css file

Now we just need a css file to make things look better. Create a file called index.css under the pages folder. Copy the content from this CSS file to the index.css file.

import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css'

That’s all. We are done. You should have the app up and running with all the shop notes created so far. We are not getting into the explanation of each of the actions on items and notes here not to make the article very lengthy. You can find all the code in the GitHub repo. At this stage, the directory structure may look like this,

A small exercise

I have not included the Create Note UI implementation in the GitHib repo. However, we have created the API already. How about you build the front end to add a shopnote? I suggest implementing a button in the header, which when clicked, creates a shopnote using the API we’ve already defined. Give it a try!

Let’s Deploy

All good so far. But there is one issue. We are running the app locally. While productive, it’s not ideal for the public to access. Let’s fix that with a few simple steps.

Make sure to commit all the code changes to the Git repository, say, shopnote. You have an account with Netlify already. Please login and click on the button, New site from Git.

Next, select the relevant Git services where your project source code is pushed. In my case, it is GitHub.

Browse the project and select it.

Provide the configuration details like the build command, publish directory as shown in the image below. Then click on the button to provide advanced configuration information. In this case, we will pass the FAUNA_SERVER_SECRET key value pair from the .env file. Please copy paste in the respective fields. Click on deploy.

You should see the build successful in a couple of minutes and the site will be live right after that.

In Summary

To summarize:

  • The Jamstack is a modern web development architecture based on client-side JavaScript, reusable APIs, and prebuilt Markup.
  • 70% – 80% of the features that once required a custom back-end can now be done either on the front end or there are APIs, services to take advantage of.
  • Fauna provides the data API for the client-serverless applications. We can use GraphQL or Fauna’s FQL to talk to the store.
  • Netlify serverless functions can be easily integrated with Fauna using the GraphQL mutations and queries. This approach may be useful when you have the need of  custom authentication built with Netlify functions and a flexible solution like Auth0.
  • Gatsby and other static site generators are great contributors to the Jamstack to give a fast end user experience.

Thank you for reading this far! Let’s connect. You can @ me on Twitter (@tapasadhikary) with comments, or feel free to follow.


The post How to create a client-serverless Jamstack app using Netlify, Gatsby and Fauna appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

December 2020 Core algorithm update

Just a heads up that Google announced theyre running a core algorithm update starting today. There hasnt been one since May 2020, which is longer than they usually go. The SEO community was expecting one back in September.

Im anxiously staring at Google Analytics to see if we come up ahead or left behind.

Has anyone else seen anything noticeable yet?

MVC Web Application With ActiveJ

Intro

In this tutorial we will create an asynchronous servlet that adds contacts to a list, parses requests and processes form validation with the help of ActiveJ framework. You can find the source code of this tutorial on GitHub.

Setting up the Project

We'll need the following dependencies:

Service Mesh Era: Building Modern Apps With YugabyteDB and Istio

Microservices architectures are becoming the de facto way developers are thinking about how their applications are constructed. But security remains a top concern for many organizations. Given the general trends of the proliferation of threats within the production network and the increased points of privileged access, it is increasingly necessary to adopt a zero-trust network security approach for microservices architectures.

One of the most common security approaches is to set up mTLS. While this is an important security tool, it’s often difficult and time-consuming to manage. To start, you have to create, distribute, and rotate keys and certificates to a large number of services. You then need to ensure you are properly implementing mTLS on all of your clients and servers. One of the compelling features of Istio is the ability to uniformly administer mTLS for all of your services without sacrificing developer productivity. While it’s true YugabyteDB provides its own TLS encryption, by having a central tool like Istio service mesh, you can set up an easy and consistent policy where Istio automatically manages the certificate rotation.

Is Service Mesh Right for Your Infrastructure?

Intro: About Microservices

The introduction of cloud-native applications and containers changed the way of how people structure and provision applications. Deploying and configuring physical servers at every edge location and trying to balance the load is just not feasible for dynamic loads and hybrid infrastructures.  The solution to this problem is microservices.

In addition to supporting dynamic scalability, the move from monolithic applications to microservices avoids the bottlenecks of a central database and supports portability and code reuse. It also provides additional benefits of easier automation, integration in CI/CD pipeline, observability, and high availability, although microservices security and management may create certain new challenges.

Shaking Down the Raspberry Pi 400

I recently got my hands on the Raspberry Pi 400, the "$70 desktop PC," and I have now had the chance to try it out for a few days. As someone who has tinkered with Raspberry Pis since the beginning, I am always excited about new products. This one is drastically different from the others. Here are my thoughts.

What Is the Raspberry Pi 400?

Collective #638




Making things move

An excellent scrolly-telling breakdown of the recreation of Walter Leblanc’s print “Torsions” with Canvas. By Varun Vachhar.

Read it




Troubleshooting Caching

Michelle Barker shares some useful steps to ensure browsers serve the latest files after deploying changes on a website.

Read it






TS belt

TS Belt is a library for functional programming in TypeScript. Inspired by the Belt module for ReScript/Reason, it solves the problem of the existence of both undefined and null.

Check it out


PWAdvent

From the 1st to the 24th of December 2020, PWAdvent introduces a new progressive browser feature every day.

Check it out







SPCSS

SPCSS is a simple and plain style sheet for text-based websites.

Check it out





The post Collective #638 appeared first on Codrops.