EDIT: Now updated with environment variables and fetch!
The future is API-driven. We have APIs for weather, payments, travel, and even sports. RESTful architecture and API frameworks are what make ordinary apps and websites into powerful tools in today's connected world.
Using these frameworks, we can create tailored experiences for users, without having to reinvent the systems that power those experiences. In this tutorial, we will use Next.js, a fantastic React-based web development framework,
This tutorial assumes you are familiar with React, Next.js, and RESTful architecture.
Initial Setup
Setting up Next.js is super simple:
npm init next-app
Next.js will set up a default project and install all dependencies for you. Once installed, inside of the pages/
directory, you will find the default Next.js index.js
welcome page. If you start the development server and make changes to this file, you will see the changes updated live in your browser.
Create the API
In this tutorial, we’ll be using Mailchimp’s API to add a new email address as a contact in a campaign mailing list.
To create an API, create a folder named api/
in the pages/
directory. Next.js will take any file inside the api/
folder and create an API instead of a page. Here, create a new file named subscribe.js
. This API will be accessible from the web at your-site.com/api/subscribe
.
Next.js provides a clean framework to handle the request and response in the API. All we need to do here is take the email address from the request and send it to Mailchimp’s API. Let’s start by exporting a default function in subscribe.js
that returns a JSON object with one key-value pair:
export default async (req, res) => {
res.end(JSON.stringify({response: 'hello world'}))
}
The async
keyword is important, as we will be using the companion await
keyword to make asynchronous calls to Mailchimp.
You can visit the API endpoint in the browser or using a tool like Postman and see the response we coded in the last step.
{
"response": "hello world"
}
In Next.js, req
and res
are default parameters sent and expected by the framework. req
is an object that contains all of the request data — headers, cookies, query values, and of course, the request body. We should only need the body at this point, accessible via the req.body
object. Let's expect a field called emailAddress
in the request, which will contain the new email address for the new subscriber. We'll pull that into a variable called email
for later.
export default async (req, res) => {
const email = req.body.emailAddress
}
To call Mailchimp's API that will add an email address to your mailing list, first create an API within your Mailchimp account. Using this key, you will authenticate your requests to Mailchimp, similar to a password. This will be stored and executed from the our subscribe
API, so no visitor to your website will ever see it.
To call APIs, we will need to use an HTTP client like fetch
, which comes bundled with Next.js.
The fetch
API is simple to use. We just need to call fetch()
with Mailchimp’s URL and an object containing the required parameters. Since fetch()
returns a Promise, we will use await
to resolve it. Since both the Promise and the fetch call could fail, we wrap the call in a try-catch
block.
try {
const response = await fetch({
// parameters will go here
})
} catch { }
The Mailchimp API documentation defines the endpoint and calls for two fields to be sent in the request: the email_address
, for which we will pass the email
value extracted from req.body
earlier, and the status
for that email address, for which we will send subscribed
. The fetch documentation shows that the first parameter in the fetch()
call is the URL, and the second parameter is an object with additional fields. The body
field is where we will pass the email_address
and status
fields. We need to use JSON.stringify()
to convert the fields into a single string.
Mailchimp’s endpoint is a POST
call, so let’s set the method
to that, and additionally define a headers
object so we can pass Content-Type
, which will be application/json
.
const email = req.body.emailAddress
try {
const response = await fetch('https://{dc}.api.mailchimp.com/3.0/lists/{listId}/members', {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Authorization': secret,
},
body: JSON.stringify({
email_address: email,
status: 'subscribed'
})
})
} catch { }
NOTE: To create the complete URL for your Mailchimp mailing list, you will need to find the dc
location and list_id
for your account in Mailchimp's dashboard.
One last step is to add the Authorization
field to the header. This will authenticate our request with Mailchimp's server with HTTP Basic Authentication using the API key created earlier. An easy way to create the Authorization token is using Postman's authorization tool. You can also create it manually by encoding your Mailchimp username and API key in Base64
.
The authorization token needs to be passed in the headers
object, but we should avoid keeping sensitive data like tokens, keys, and passwords unencrypted as strings in a file. Instead, let’s create an environment variable that will be encrypted and stored securely outside of our code. Our app will find and use it automatically.
Create a .env
file in the root of the project. This will store a list of environment variables as key-value pairs. The key can be anything, and the value will be the Base64
encoded token for Mailchimp. Remember to wrap the value in quotes.
MAILCHIMP_SECRET="Basic s0m3L0ngR@ndomStr1nG"
Don’t forget to ignore this file in your source control — we don’t want to be syncing this plaintext file. It is best to recreate this file wherever your code will run. This file will help run your code on your local machine, and you can set up environment variables on most cloud platforms.
Once the token is saved, we can pull it from the env
object and send it in our fetch
request:
const { MAILCHIMP_AUTH: secret } = process.env
// { ... }
try {
const response = await fetch('https://{dc}.api.mailchimp.com/3.0/lists/{listId}/members', {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Authorization': secret,
},
body: JSON.stringify({
email_address: email,
status: 'subscribed'
})
})
} catch { }
Now we just need to return the correct response from our API depending on the response
we get from Mailchimp. We will only send back a response status, and leave the response body empty since there is no data to be communicated back to the browser. To keep things simple in this tutorial, if Mailchimp returns a 200
response status, we will also return a 200
. If Mailchimp returns anything else, we will return a 400
status. It either subscribed the user, or it didn't.
// const response = { ... }
if (response.status === 200) {
res.statusCode = 200
res.end()
} else {
res.statusCode = 400
res.end()
}
Now, fetch
will throw an error if the call fails. This could be due to a network issue or a legitimate error returned from the Mailchimp API. This error will be caught in the catch
block, so let's make sure it returns a response too.
// try { ...
} catch (error) {
res.statusCode = 400
res.end()
}
And that's it! We have an API that will call Mailchimp with an email address and return a status code depending on Mailchimp's response. If you run the development server, you can test this in Postman by sending an email address in the body of a POST
request. In response, we will either get a 200
code or 400
code, just as we coded for.
{
"emailAddress" : "user@example.com"
}
In the next part of this tutorial, we will set up some validation and security in our API before deploying to the web, and we will also set up the frontend component — that is, the form itself.
Top comments (0)