Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/vseplet/apifly

Cross runtime state sharing library on HTTP
https://github.com/vseplet/apifly

Last synced: about 2 months ago
JSON representation

Cross runtime state sharing library on HTTP

Awesome Lists containing this project

README

        

Apifly


Apifly



Apifly JSR Badge


Apifly - лёгкая и гибкая библиотека для организации клиент-серверного взаимодействия, поддерживающая RPC и обмен состоянием с возможностью кэширования, фильтров, guards и watchers.

Содержание:


Описание


Apifly — это лёгкая и гибкая библиотека для организации клиент-серверного взаимодействия, поддерживающая удалённые вызовы процедур (RPC) и обмен состоянием. Она упрощает создание API, предоставляет встроенные возможности для кэширования, использования guard-функций, наблюдателей (watchers) и фильтров. Apifly помогает синхронизировать состояние между клиентом и сервером с минимальными усилиями и строгой типизацией.

Быстрый старт

1. Определение состояния и процедур


Для начала необходимо определить тип состояния и процедур, которые будут использоваться в вашем приложении.

```ts
import { ApiflyDefinition } from "@vseplet/apifly/types";

export type MyApiflyDefinition = ApiflyDefinition<
{
counter: number;
message: string;
user: {
tg_id: string;
};
},
{
incrementCounter: {
args: [number];
returns: string;
};
resetCounter: {
args: [];
returns: string;
};
getMessage: {
args: [];
returns: string;
};
},
{
userId: string;
}
>;
```

2. Настройка сервера


Пример настройки сервера на базе фреймворка Hono и использования Apifly для управления состоянием:

```ts
import apifly from "@vseplet/apifly";
import type { ApiflyDefinition } from "@vseplet/apifly/types.ts";
import { Hono } from "jsr:@hono/hono";

type MyApiflyDefinition = ApiflyDefinition<
{
counter: number;
message: string;
user: {
tg_id: string;
};
},
{
incrementCounter: {
args: [number];
returns: string;
};
resetCounter: {
args: [];
returns: string;
};
getMessage: {
args: [];
returns: string;
};
},
{
userId: string;
}
>;

let database: Record = {};

// Функции для симуляции чтения/записи данных
async function readFromDatabase(userId: string) {
console.log(`Reading state for userId: ${userId}`);
await new Promise((resolve) => setTimeout(resolve, 2000));

if (!database[userId]) {
database[userId] = {
counter: 0,
message: "Initial message",
user: { tg_id: userId },
};
}
return database[userId];
}

async function writeToDatabase(userId: string, newState: any) {
console.log(`Writing state for userId: ${userId}`);
database[userId] = newState;
}

const apiflyManager = new apifly.manager(
true,
4000,
"userId",
)
.load(async (args) => await readFromDatabase(args.userId))
.unload(async (args) => await writeToDatabase(args.userId, args.state))
.procedure("incrementCounter", async (args, state) => {
state.counter += args[0];
return `Counter incremented by ${args[0]}, new value: ${state.counter}`;
})
.procedure("resetCounter", async (args, state) => {
state.counter = 0;
return "Counter reset to 0";
})
.procedure("getMessage", async (args, state) => state.message)
.guard("counter", ({ newValue }) => newValue >= 0)
.watcher("counter", async ({ newValue, currentValue, userId }) => {
console.log(
`Watcher: Counter changed from ${currentValue} to ${newValue} for user ${userId}`,
);
})
.filter("message", ({ currentValue }) => !currentValue.includes("secret"));

const apiflyServer = new apifly.server(
apiflyManager,
"/api/apifly",
{
userId: "X-User-ID",
},
);

const server = new Hono();
apiflyServer.registerRoutes(server);

console.log("Server is running");
Deno.serve(server.fetch);
```

3. Создание клиента


Пример настройки клиента с указанием заголовков:

```ts
import apifly from "@vseplet/apifly";
import type { MyApiflyDefinition } from "./MyApiflyDefinition.type.ts";

export const client = new apifly.client({
baseURL: "https://apiflyservertesting.deno.dev/api/apifly",
headers: {
"X-User-ID": "user10",
},
limiter: { unlimited: true },
});
```

Пример использования клиента:

GET запрос:

```ts
const [state, error] = await client.get();
console.log(state);
```

PATCH запрос:

```ts
const patchedState = await client.patch({
message: "Updated message!",
});
console.log(patchedState);
```

Вызов процедуры:

```ts
const [result, error] = await client.call("incrementCounter", [5]);
console.log(result);
```

Пример работы с кэшем

```ts
const [state, error] = await client.get();
```

Установка


Для установки используйте JSR:

```sh
jsr install @vseplet/apifly
```

Поддержка и обратная связь


Этот модуль находится в активной разработке, и автор будет рад любым предложениям, исправлениям.