Chapter 11: APIs – Extending Gatsby

In this chapter, you will learn about the A part of the Jamstack—that is, Application Programming Interfaces (APIs). We will learn how to use them within the dynamic portion of a compiled web page to recreate the functionality that web developers are familiar with in traditional server-based web development. We are going to create a custom Propose an event form using a Netlify form, and we are going to manage submissions through Netlify functions. We will also see how to connect a third-party service to our Gatsby application.

We will cover the following topics in this chapter:

  • Introduction to APIs
  • Gatsby – APIs

Technical requirements

We will need the following applications to thoroughly understand this chapter:

  • Terminal
  • The Gatsby application installed
  • A Netlify account

The code files for this chapter can be found at https://github.com/PacktPublishing/Jumpstart-Jamstack-Development/tree/chapter_eleven.

Introduction to APIs

APIs have been around almost since we started programming. Modern APIs started to be come as we know them now in the early 2000s, when companies such as Amazon started to provide access to their data through HyperText Transfer Protocol (HTTP) requests. These companies changed the way we did business online. Developers could now get and post user information from services such as Salesforce and provide a full e-commerce experience on their application using APIs.

In 2004, with the introduction of social networks, we changed the way we were using the internet. Companies such as Facebook and Twitter started developing their own APIs. Similar to the e-commerce experience, developers could now get a user's profile information, events, and pictures from social networking applications.

A few years later, the new generation of smartphones came out. People started navigating the internet through their mobile phones and developers started developing applications that could be installed on a smartphone, and APIs were the right way to connect to these services. Instagram changed the way we were sharing photos on the internet and provided their own API a few years later.

Around 2010, we had desktop and smartphone devices consuming APIs and relying on third-party web services through web applications and mobile applications and, around 2015, more devices got smarter. Every device that could connect to the internet could access the API resources of a web service. Smart speakers, thermostats, watches, and many other devices started consuming APIs.

Amazon Alexa, Google Nest, Fitbit, and Apple Watch are just a few of many devices we now use every day that can get data from APIs.

Let's explore the Gatsby API in the next section.

Gatsby – APIs

In this section, we are going to explore how to use APIs inside Gatsby. In the example that we will build in this chapter, we will create an event form whereby anonymous users can propose their event. When the user submits the form, we will add the submission to Sanity via an API.

To achieve this, we will do the following:

  • Create a Netlify form on the home page of our events application.
  • Configure a token from Sanity so that we can submit the form via an API.
  • Configure a Netlify function to send data on submission.

Creating a Netlify form

As our third-party service, we will use Netlify Forms, a built-in form-handling functionality provided by Netlify. When the code is deployed to Netlify, the system automatically detects the form and creates a form submission page in your Netlify site's admin panel.

To create a Netlify form, simply add the netlify="true" attribute data to the <form> tag, add the <input type="hidden" name="form-name" value="YOUR_VALUE" /> hidden field, and you are ready to go.

Our form will have the following fields:

  • Full Name
  • Email
  • Event title
  • Date
  • Venue
  • Virtual
  • Event URL
  • Description

We will add our form to our home page just before the footer, as follows:

  1. Open the index.js file located under /web/src/pages/.
  2. Right before the closing container tag (</Container>) we can add our form, like this:

    <form name="propose-event" method="POST" data-netlify="true" >

      <input type="hidden" name="form-name" value="propose-event" />

    </form>

    As you can see, we have added the two parameters needed to be able to submit a form into Netlify.

  3. Let's keep adding the other fields, as follows:

    <form name='propose-event' method='POST' data-netlify='true' >

              <input type='hidden' name='form-name' value='propose-event' />

              <div className='field'>

                <label className='label'>Full name:

                  <input className='input' type='text' name='name'/>

                </label>

              </div>

              <div className='field'>

                <label className='label'>Email:

                  <input className='input' type='email' name='email'/>

                </label>

              </div>

              ...

              <div className='field'>

                <label className='label'>Message:

                  <textarea className='textarea' name='message'></textarea>

                </label>

              </div>

              <div className='field'>

                <button className='button' type='submit'>Send

                </button>

              </div>

            </form>

    The venue field will get venues from our site. Let's add the query to get all the venues.

  4. In our index.js page, inside the IndexPageQuery query, we can add the query to get all the IDs and names of the venues, as follows:

    Query IndexPageQuery {

      ...

      venues: allSanityVenue {

          edges {

            node {

              _id

              name

           }

          }

        }

      ...

  5. Map the data inside a constant called venueNodes, as illustrated in the following code snippet:

      const venueNodes = (data || {}).venues

        ? mapEdgesToNodes(data.venues)

        : []

  6. Add our venue field to the form, like this:

    <div className="field">

      <label className="label">Venue:

        <select className="select" name="venue">

           {

             venueNodes && venueNodes.map((venue) => (

                <option id={venue._id}>{venue.name}</option>

              ))

            }

        </select>

      </label>

    </div>

    Now that our HTML form is ready, it should look like this:

Figure 11.1 – Form under the Gatsby application home page

Figure 11.1 – Form under the Gatsby application home page

We are ready to push it to GitHub.

Deploying the form to Netlify

As we know, when we push the code up GitHub, it automatically deploys to Netlify as shown in the following steps:

  1. Once it is deployed to Netlify, we will be able to see the form in our Netlify site's admin panel under the Forms tab, as illustrated in the following screenshot:
    Figure 11.2 – Forms tab

    Figure 11.2 – Forms tab

  2. If you click on Forms, you will see Submissions, as depicted in the following screenshot:
    Figure 11.3 – Netlify Forms page

    Figure 11.3 – Netlify Forms page

    Let's add a new submission.

  3. Go to your Gatsby live site on Netlify and complete the form. After you click Send, you will receive the following confirmation message:
    Figure 11.4 – Netlify submission success page

    Figure 11.4 – Netlify submission success page

  4. Now, let's go back to the Netlify form admin panel to see our submission, as illustrated in the following screenshot:
Figure 11.5 – Netlify submissions list

Figure 11.5 – Netlify submissions list

As you can see, we have our form submission on Netlify.

Now, let's extend our form and use the Sanity API to get and insert information.

Configuring a token form in Sanity

When a new form is submitted, we need to add a new event into our Sanity application. In order to do that, we create a token that gives permission to our function to access Sanity and create an Event.

We also need to add a new 'approved' field to our events so that we avoid the publication of unwanted events on our Sanity application.

Creating an approved field

We will create a boolean field that will define whether an event has been approved or not.

Open the event schema file located under studio/schemas/documents.index.js and add the new field inside the fields array, like this:

export default {

  name: 'event',

  type: 'document',

  title: 'Event',

  fields: [

    ...

    {

      name: 'approved',

      type: 'boolean',

      title: 'Approved'

    },

    ...

  ]

}

Save the file and restart your local application. Now, you should see the field in your local Sanity application.

To deploy the field to production, from the Terminal go inside the /studio folder and type the following command:

sanity graphql deploy

Deploying a Sanity token

As a first step, we will generate a new token specifically for this form. To do that, go into your Manage Sanity admin panel (https://manage.sanity.io/) and click on your project. Then, proceed as follows:

  1. Go to Site Settings | API and scroll down to Tokens. The existing token is used by Gatsby to retrieve the content from Sanity. Now, we need to generate a new token to write data into Sanity.
  2. Click on the blue ADD NEW TOKEN button, as illustrated in the following screenshot:
    Figure 11.6 – Tokens

    Figure 11.6 – Tokens

  3. Insert a title, and then select the Rights permission as Write. This permission gives the user the ability (right) to read, write, and delete data. Now, click on the green ADD NEW TOKEN button, as illustrated in the following screenshot:
    Figure 11.7 – Adding a new token

    Figure 11.7 – Adding a new token

    A new token is generated and prompted to you.

  4. Copy the token, and now go back to your Netlify project and click on Settings | Build & deploy | Environment.

    In this section of the settings, it is possible to store the token securely as an environment variable, as highlighted in the following screenshot:

    Figure 11.8 – Netlify Environment variables settings page

    Figure 11.8 – Netlify Environment variables settings page

  5. Click on Edit variables | New variable.
  6. Add your new token, called SANITY_STUDIO_PROPOSE_EVENT, and click on Save, as illustrated in the following screenshot:
Figure 11.9 – Netlify Environment variables settings page

Figure 11.9 – Netlify Environment variables settings page

Now that we have the token in place, we can insert a new document into Sanity with our custom form.

Configuring a Netlify function

Netlify functions are Amazon Web Services (AWS) Lambda functions that let you run code without configuring or managing servers.

Let's see how to configure it inside Netlify, as follows:

  1. As a first step, we need to tell Netlify in which directory our serverless functions are. Netlify will look into the given directory on each deployment, and it will deploy the functions into AWS.
  2. Let's create a folder named functions inside our web directory, and a Netlify configuration file called netlify.toml.

    Inside our netlify.toml file we can tell where our functions will be, as illustrated in the following code snippet:

    [build]

      base = "."

      functions = "./web/functions"

  3. As a first test, we will create a simple Hello World script.
  4. Create a hello-world.js file inside web/functions and add the following code:

    // /web/functions/hello-world.js

    exports.handler = async function() {

      return {

        statusCode: 200,

        body: "Hello world from a Netlify Function!",

      };

    }

    Great—we have now created our first function. The function will be available under https://yoursite.com/.netlify/functions/hello-world.

  5. To run it locally, we need to install the Netlify command-line tool. To do that, from the Terminal type the following command:

    npm install -g netlify-cli

  6. Once the netlify-cli tool is installed, from the Terminal go into the /web directory and type the following command:

    netlify link

  7. Select the correct project by selecting the project created in GitHub when prompted by the following message:
    Figure 11.10 – Terminal

    Figure 11.10 – Terminal

  8. Select the Gatsby application (the one that ends with web); that is hands-on-jamstack-web in our case, as illustrated in the following screenshot:
    Figure 11.11 – Terminal

    Figure 11.11 – Terminal

    Now, the linking is done.

  9. Once the link is done, inside the web directory type the following command:

    netlify dev

    This command will start your Gatsby project and set up an AWS Lambda server, and it launches a server on port 8888.

  10. Now, you can access your local site from http://localhost:8888 and see your function output from http://localhost:8888/.netlify/functions/hello-world, as illustrated in the following screenshot:
Figure 11.12 – Netlify function on our Gatsby application

Figure 11.12 – Netlify function on our Gatsby application

In this section, we have created a new Netlify form on our Gatsby home page, created a token on Sanity to let Netlify insert a new proposed event, and configured our Netlify function folder.

In the next section, we are going to create a function that inserts a new proposed event into our Sanity dataset.

Creating the submission-created.js file

Netlify form submission triggers a submission-created event. Execute the following steps to create the .js file:

  1. Create a file inside web/functions called submission-created.js. This function will handle submissions from the Netlify form.
  2. Next, create export.handler for this function, as follows:

    exports.handler = async (event, context, callback) => {

    }

    This handler receives an event object that contains path, httpMethod, headers, queryStrinparameters, body, and isBase64Encoded.

    The context parameter includes information such as user identity information. The callback parameter is similar to the callback parameter in an AWS Lambda function. The code can be seen in the following snippet:

    exports.handler = function(event, context, callback) {

        callback(null, {

        statusCode: 200,

        body: "Hello, World"

        });

    }

    Sanity provides the Client API to add content via the API.

  3. In our submission-created.js file, let's add the client at the top of the file, like this:

    const sanityClient = require('@sanity/client')

    exports.handler = function(event, context, callback) {

        callback(null, {

        statusCode: 200,

        body: "Hello, World"

        });

    }

  4. To initialize the client, we need to provide the Sanity project ID, dataset name, and an access token. In our Sanity application home page, our local is under http://localhost:3333. Get the project ID and the dataset used from your Sanity manager console.
  5. We have created the access token in the previous section, and we can now reuse it, as follows:

    const sanityClient = require('@sanity/client')

    const client = sanityClient({

      projectId: 'my_project_id',

      dataset: 'my_dataset',

      token: process.env.SANITY_STUDIO_ADD_EVENT

    })

    exports.handler = function(event, context, callback) {

        callback(null, {

        statusCode: 200,

        body: "Hello, World"

        });

    }

  6. Now, we can use the create(doc) method to add a new event to Sanity.
  7. The client method requires a plain JavaScript object representing the document. It must include a _type attribute.

    Let's start building our document. Our Events fields are as follows:

    Title

    Date

    Event URL

    Venue

    Virtual

    Description

  8. Inside our handler, we must get the body of the event, as follows:

    exports.handler = async function(event, context, callback) {

      const { payload } = JSON.parse(event.body)

      ...

    }

  9. Now, we can map the fields inside the payload, like this:

    const doc = {

        _type: 'event',

        name: payload.data.eventTitle,

        dateAndTime: payload.data.date,

        virtual: payload.data.virtual === 'on',

        eventUrl: payload.data.eventUrl,

        venue: {

          _ref: payload.data.venue,

          _type: 'reference'

        },

        body: [{

          '_type': 'block',

          'children': [{

            '_type': 'span',

            'text': payload.data.message

          }]

        }],

        approved: false

    }

  10. Now that our document is ready, we can pass it to the create(doc) function, as follows:

    const sanityClient = require('@sanity/client')

    const client = sanityClient({

      projectId: 'my_project_id',

      dataset: 'my_dataset',

      token: process.env.SANITY_STUDIO_ADD_EVENT

    })

    exports.handler = async function(event, context, callback) {

      const { payload } = JSON.parse(event.body)

      const doc = {

        ...

      }

      // Create document

      await client.create(doc)

        .then(res => {

          callback(null, {statusCode: 200})

        })

    }

And it's done. Now, add the code to Git and push it to the master. Once the deployment is finished, we can test it in our production environment.

In your live Gatsby application, fill in the form and press Send, as shown in Figure 11.1. A new submission will be added on Netlify Forms, and the content will be added to Sanity from Gatsby using the Netlify function.

Summary

In this chapter, we have learned how to use Netlify Forms to help make creating and managing form submissions frictionless. We have extended the Netlify form with our own action on submit, using the power of the Netlify functions. At the end, we used the Sanity API to create new Event content from a Netlify form using Netlify functions.

In the next chapter, we are going to create an Alexa skill that will read events from our Sanity dataset.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset