feat(zod-bird.mdx): add documentation for zod-bird library

This commit adds documentation for the zod-bird library. It includes
examples of how to use the library to ingest data and query endpoints.
It also includes information on how to use caching with the library.
This commit is contained in:
chronark 2023-05-22 22:16:56 +02:00
parent 10237b1a63
commit bfe2584a5e
No known key found for this signature in database

View File

@ -0,0 +1,172 @@
---
title: "Zod Bird"
description: Zodbird is an e2e typed tinybird.co client library for typescript, leveraging zod for type safety and transformations
repository: chronark/zod-bird
date: "2023-05-21"
published: true
---
- typesafe
- handles building the url params for you
- easy transformation of resulting data
- built in cache directives for nextjs
- built in retry logic for ratelimited requests
```ts
import { Tinybird } from "@chronark/zod-bird";
import { z } from "zod";
const tb = new Tinybird({ token: "token" });
export const getEvents = tb.buildPipe({
pipe: "get_events__v1",
parameters: z.object({
tenantId: z.string(),
}),
data: z.object({
event: z.string(),
time: z.number().transform((t) => new Date(t)),
}),
});
const res = await getEvents({ tenantId: "chronark" })
// res.data = {event: string, time: Date}[]
```
## Install
```
npm i @chronark/zod-bird
```
## Ingesting Data
```ts
// lib/tinybird.ts
import { Tinybird } from "./client";
import { z } from "zod";
const tb = new Tinybird({ token: process.env.TINYBIRD_TOKEN! });
export const publishEvent = tb.buildIngestEndpoint({
datasource: "events__v1",
event: z.object({
id: z.string(),
tenantId: z.string(),
channelId: z.string(),
time: z.number().int(),
event: z.string(),
content: z.string().optional().default(""),
metadata: z.string().optional().default(""),
}),
});
```
```ts
// somewhere.ts
import { publishEvent } from "./lib/tinybird";
await publishEvent({
id: "1",
tenantId: "1",
channelId: "1",
time: Date.now(),
event: "test",
content: "test",
metadata: JSON.stringify({ test: "test" }),
});
```
## Querying Endpoints
```ts
// lib/tinybird.ts
import { Tinybird } from "./client";
import { z } from "zod";
const tb = new Tinybird({ token: process.env.TINYBIRD_TOKEN! });
export const getChannelActivity = tb.buildPipe({
pipe: "get_channel_activity__v1",
parameters: z.object({
tenantId: z.string(),
channelId: z.string().optional(),
start: z.number(),
end: z.number().optional(),
granularity: z.enum(["1m", "1h", "1d", "1w", "1M"]),
}),
data: z.object({
time: z.string().transform((t) => new Date(t).getTime()),
count: z
.number()
.nullable()
.optional()
.transform((v) => (typeof v === "number" ? v : 0)),
}),
});
```
```ts
// somewhere.ts
import { getChannelActivity } from "./lib/tinybird";
const res = await getChannelActivity({
tenantId: "1",
channelId: "1",
start: 123,
end: 1234,
granularity: "1h"
})
```
`res` is the response from the tinybird endpoint, but now fully typed and the data has been parsed according to the schema defined in `data`.
## Advanced
### Caching
You can add cache directives to each pipe.
#### Disable caching (useful in Next.js where everything is cached by default)
```ts
tb.buildPipe({
pipe: "some_pipe__v1",
parameters: z.object({
hello: z.string()
}),
data: z.object({
response: z.string()
}),
opts: {
cache: "no-store" // <-------- Add this
};
});
```
#### Cache for 15 minutes
```ts
tb.buildPipe({
pipe: "some_pipe__v1",
parameters: z.object({
hello: z.string()
}),
data: z.object({
response: z.string()
}),
opts: {
revalidate: 900 ;// <-------- Add this
};
});