StepZen Stickers: The Code Behind the Fun
There's something joyful about a sticker - the glossy laminated colors, the pure potential before you peel away the backing and decide whether to display it on a laptop, water bottle, or skateboard. Stickers, like mini badges of honor, reflect your lived experiences.
So when it came to swag, stickers were an obvious choice for us here at StepZen.
But how to get them to you? The simplest way was to use our own service!
Read on to see how we collected and verified your address information to send you our stickers-- see exactly how StepZen's GraphQL data layer brought ease to our integration of two initially separate backends.
The Overall Structure of the Code
Since our website was a Next app, we added a stickers.js
page in the /pages
directory to display the UI and take in the information for the GraphQL query from the user.
Next.js has a very easy way of creating pages. If you add any javascript file to the directory pages/
, it will create that route in the application.
We imported a route, pages/api
that executes HTTP fetch calls to a StepZen GraphQL endpoint and requires API key authentication to access.
We imported the fetch calls themselves from the Next pages/api
folder.
These calls were made to a StepZen endpoint, which was setup with a StepZen folder. Let's go into a little more detail on this folder's structure.
Keep the file structure code block --- The StepZen endpoint is setup with a StepZen folder made in the root of our project. Let's go into a little more detail on this folder's structure.
.
├── stepzen
├── airtable.graphql
├── lob.graphql
├── index.graphql
├── config.yaml
└── stepzen.config.json
Here, airtable.graphql
and lob.graphql
contain the types, queries, and mutations that define our graphql schemas. We'll go into more detail on what they look like in the next couple of sections.
index.graphql
contains the airtable.graphql
and lob.graphql
schemas:
schema @sdl(files: ["airtable.graphql", "lob.graphql"]) {
query: Query
}
Basically, it tells StepZen which schemas to make available on the StepZen endpoint, by naming them within files: [...]
.
config.yaml
contains the configuration details for the APIs so StepZen can access them. In this case the details we provide are:
configurationset:
- configuration:
name: airtable_config
Authorization: Bearer KEY_HERE
baseid: BASE_ID_HERE
- configuration:
name: lob_config
Authorization: Basic KEY_HERE
Lastly, stepzen.config.json
holds the name of our endpoint:
{
"endpoint": "api/website"
}
Connecting to Lob
Our first query on our Stickers page will make a fetch call to Lob, an address verification API. Here's what it looks like in our lob.graphql
schema.
This query goes to Lob, an address verification API. This ensures that the user is entering their address correctly. Here's what it looks like in our GraphQL schema:
type Mutation {
"""
Send the address details
to verify if the shipment
will be deliverable.
Equivalent To POST /v1/us_verifications
"""
lob_us_verification(
"""
The address
"""
primary_line: String!
"""
The city.
"""
city: String!
"""
The state in abbreviated format.
"""
state: String!
"""
The zipcode in 5 digit format.
"""
zip_code: String!
): Lob_US_Verification
@rest(
method: POST
contenttype: "application/x-www-form-urlencoded"
endpoint: "https://api.lob.com/v1/us_verifications"
configuration: "lob_config"
)
}
You can see that we're using the custom StepZen directive @rest
to post to the endpoint, specifying:
method
- the method that the http request will usecontenttype
- the content type of the mutationendpoint
- the endpoint the directive connects toconfiguration
- the name of the configuration keys etc inconfig.yaml
This sets defines the mutation so if we run:
mutation MyMutation {
lob_us_verification(
city: "Washington"
primary_line: "1600 Pennsylvania Avenue, N.W."
state: "D.C."
zip_code: "20500"
) {
id
deliverability
}
}
Then we get an id and deliverability confirming verification:
{
"data": {
"lob_us_verification": {
"id": "us_ver_f527198c03e7480e9ff9"
"deliverability": "deliverable"
}
}
}
Connecting to Airtable
Once the address has been verified by the Lob API, it can be stored in Airtable.
The mutation StepZen used to log the address information into Airtable looks like:
type Mutation {
createShipment(
firstname: String!
lastname: String!
address: String!
apartment: String!
city: String!
state: String!
zip: String!
): Airtable_Shipment
@rest(
method: POST
resultroot: "records[]"
postbody: "{\"records\":[{\"fields\":{\"firstname\":\"{{.Get \"firstname\" }}\",\"lastname\":\"{{.Get \"lastname\" }}\",\"address\":\"{{.Get \"address\" }}\",\"apartment\":\"{{.Get \"apartment\" }}\",\"city\":\"{{.Get \"city\" }}\",\"state\":\"{{.Get \"state\" }}\",\"zip\":\"{{.Get \"zip\" }}\"}}]}"
endpoint: "https://api.airtable.com/v0/$baseid/Addresses"
configuration: "airtable_config"
)
}
Here, @rest
defines the
method
- the method that the http request will useresultroot
- this defines the top layer of json so StepZen can 'peel' it off and you don't have to specify 'records' in your query.postbody
- the information held in the postbodyconfiguration
- the name of the configuration keys etc inconfig.yaml
This defines the Airtable mutation so you can send:
mutation MyMutation {
createShipment(
address: "1600 Pennsylvania Avenue, N.W."
apartment: ""
city: "Washington"
firstname: "Joe"
lastname: "Biden"
state: "D.C."
zip: "20500"
) {
createdTime
id
}
}
and see the address in Airtable!
Conclusion
After defining the schemas inside the StepZen folder, all it took were a couple axios calls in our API which used information from the frontend captured by Next.js, and our stickers page was live!
We enjoyed the process of using StepZen to make it, and we hope you enjoyed learning about it! Feel free to grab a sticker. :)