Skip to main content

· One min read
Josh Twist

Length: 2 minutes

Zuplo is so fast and flexible, it is the easiest way to setup a mock API. Here we create a simple todo API (of course 🤦🏼‍♂️). We add our 'sleep' policy to make it slow too - so you can call this from your UI client and simulate long loading times.

Here's the code for the request handler:

import { ZuploContext, ZuploRequest } from "@zuplo/runtime";

export default async function (request: ZuploRequest, context: ZuploContext) {
return [
{ text: "Learn Javascript", done: false },
{ text: "Learn Typescript", done: false },
{ text: "Play around in Zuplo", done: true },
{ text: "Build something awesome", done: true },
];
}

Have fun, APIFiddling!

· One min read
Josh Twist

Length: 2 minutes

In this post we pickup where left off in this post Gateway over SaaS? and take our AirTable API and make it work directly with a form POST from a website.

It even has a honeypot field to filter out simple bots 👏

Here's the form post code from JSFiddle

<form method="POST" action="<YOUR ZUPLO API URL HERE>">
<input type="text" name="name" value="" />
<input type="text" name="email" value="" />
<input type="text" style="display:hidden" name="hp" value="" />
<button>submit</button>
</form>

· One min read
Josh Twist

Length: 2 minutes

This one's a little extra. Zuplo is so programmable you can use it in ways you've never considered for a gateway... a gateway over SaaS APIs - like AirTable.

In this example we use the Event Planning Template.

And here's the code in our request handler

import { ZuploContext, ZuploRequest } from "@zuplo/runtime";
import env from "@app/environment";

export default async function (request: ZuploRequest, context: ZuploContext) {
const body = await request.json();

const data = {
records: [
{
fields: {
Name: body.name,
Email: body.email,
},
},
],
};

const response = await fetch(env.ATTENDEES_URL, {
method: "POST",
headers: {
Authorization: `Bearer ${env.API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});

if (!response.ok) {
return new Response("Error calling AirTable!", {
status: 500,
});
}
return new Response("Success", {
status: 200,
});
}

· 2 min read
Josh Twist

Length: 3 minutes

One of my favorite features of Zuplo is the ability to build custom policies. Here we create a custom policy to archive every request to Amazon's S3 storage. Here's the code in our archive-request.ts module:

import { ZuploContext, ZuploRequest } from "@zuplo/runtime";
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import env from "@app/environment";

type MyPolicyOptionsType = {
myOption: any;
};
export default async function (
request: ZuploRequest,
context: ZuploContext,
options: MyPolicyOptionsType,
policyName: string
) {
context.log.info(env.AWS_SECRET_ACCESS_KEY);

const s3Client = new S3Client({ region: "us-east-2" });
const file = `${Date.now()}-${crypto.randomUUID()}.req.txt`;

const clone = request.clone();

const uploadParams = {
Bucket: "request-storage",
Key: file,
Body: await clone.text(),
};

const data = await s3Client.send(new PutObjectCommand(uploadParams));

return request;
}

Note, the code above will update S3 in serial with invoking your API, which will increase the latency of your API. However, you can also do this asynchronously, as follows:

import { ZuploContext, ZuploRequest } from "@zuplo/runtime";
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import env from "@app/environment";

type MyPolicyOptionsType = {
myOption: any;
};
export default async function (
request: ZuploRequest,
context: ZuploContext,
options: MyPolicyOptionsType,
policyName: string
) {
context.log.info(env.AWS_SECRET_ACCESS_KEY);

const s3Client = new S3Client({ region: "us-east-2" });
const file = `${Date.now()}-${crypto.randomUUID()}.req.txt`;

const clone = request.clone();

const uploadParams = {
Bucket: "request-storage",
Key: file,
Body: await clone.text(),
};

const dataPromise = s3Client.send(new PutObjectCommand(uploadParams));
// This tells the runtime to not shutdown until that promise is complete
context.waitUntil(dataPromise);

return request;
}

· One min read
Josh Twist

Length: 2 minutes

Bad inputs can easily break your API. Stop bad form before it even hits your API with Zuplo. In this demo we show how you can add JSON validation to an API without touching your original API.

We use JSON Schema with our JSON Validation policy. Here's the schema:

{
"title": "Person",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The person's first name.",
"pattern": "\\S+ \\S+"
},
"company": {
"type": "string"
}
},

"additionalProperties": false,
"required": ["name"]
}

Easy peasy.

· One min read
Josh Twist

Length: 2 minutes

We continue with the example from this post and add smart routing based on claims in the token.

Here's the function handler we create to do the smart routing

import { ZuploContext, ZuploRequest } from "@zuplo/runtime";

export default async function (request: ZuploRequest, context: ZuploContext) {
const data = request.user.data;
if (data["https://example.com/claim1/"] === "this-is-a-claim"){
return fetch("https://example.com");
}
else {
return fetch(`https://ecommerce-legacy.zuplo.io/objects?type=products&id=${request.params.productId});
}
}

· One min read
Josh Twist

Length: 2 minutes

Here we show how easy it is to add JWT authentication to an API using the Zuplo gateway. We extend the demo from this post.

There was no code required for this sample, it's that easy 🙌

· One min read
Josh Twist

Length: 3 minutes

In this video we see just how programmable the Zuplo gateway is by going full tilt and building a simple API using Function Handlers 🤯

We also look at wildcard routes like so /(.*).

Here's the code from the echo API we create

import { ZuploContext, ZuploRequest } from "@zuplo/runtime";

export default async function (request: ZuploRequest, context: ZuploContext) {
const { url, query } = request;

const body = await request.text();

return { url, query, body };
}