Length: 2 minutes
Let's go on a quick tour of the Zuplo Portal - we talk about our built-in super-fast build with error notifications, analytics, live logs and more.
Critical viewing for new Zuplo users.
Length: 2 minutes
Let's go on a quick tour of the Zuplo Portal - we talk about our built-in super-fast build with error notifications, analytics, live logs and more.
Critical viewing for new Zuplo users.
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!
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>
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,
});
}
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;
}
Length: 2 minutes
Here we introduce the Basic Authentication policy and combine it with our secure environment settings capability.
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.
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});
}
}
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 🙌
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 };
}