chronark bfe2584a5e
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.
2023-05-22 22:16:56 +02:00

173 lines
3.3 KiB
Plaintext

---
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
};
});