npm package: @fluxninja/aperture-js
Description: Flow control SDK that interfaces with FluxNinja Aperture Agents
Author: FluxNinja, Inc.
Latest version: 2.12.0

<p align="center">
🚀 <b></b>Just launched v1 of <a href="https://blog.fluxninja.com/blog/aperture-v1-launch-2024/">managed rate limiting service</a></b>
  <br/>Support us with your feedback and questions on <a href="https://www.producthunt.com/posts/fluxninja-aperture">Product Hunt</a> or <a href="https://discord.gg/U3N3fCZEPm">Discord</a>
  <br/>
</p>

<p align="center">
  <img src="https://github.com/fluxninja/aperture/raw/main/docs/content/assets/img/aperture_logo.png" alt="FluxNinja Aperture" width="75%">
  <br/>
  <a href="https://docs.fluxninja.com">
    <img alt="Documentation Reference" src="https://img.shields.io/badge/documentation-reference-brightgreen?style=for-the-badge&logo=data:image/png;base64,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">
  </a>
  <a href="https://join.slack.com/t/fluxninja-aperture/shared_invite/zt-1eunlrkhh-10P1HUkmBfVJX3qrSLRk~g">
    <img alt="Slack Community" src="https://img.shields.io/badge/Join%20Our%20Community-Slack-brightgreen?style=for-the-badge&logo=slack">
  </a>
  <a href="https://dl.circleci.com/status-badge/img/gh/fluxninja/aperture-js/tree/main.svg?style=svg&circle-token=3355ec6bf64c89b5592804fe48726a2d78d49c17">
    <img alt="Build Status" src="https://img.shields.io/circleci/build/github/fluxninja/aperture-js/main?token=3355ec6bf64c89b5592804fe48726a2d78d49c17&style=for-the-badge&logo=circleci">
  </a>
</p>

# Rate Limiting for JavaScript or Node.js Applications

The `aperture-js` SDK provides an easy way to integrate your JavaScript
applications with [FluxNinja Aperture](https://github.com/fluxninja/aperture).
It allows flow control functionality on fine-grained features inside service
code.

Refer [documentation](https://docs.fluxninja.com/sdk/javascript/) for more
details.

## Use Cases and Features

Aperture provides rate limiting, caching, and api quota management to
effectively manage the load on your application. With its unique approach that
separates application code from rate limiting code/infra, it can effectively
handle various use cases of rate limiting such as:

- Enforcing or complying with
  - Rate-limits based on no. of requests per second
  - Per-user rate-limits based on consumed tokens (e.g. quota mangement for GPT
    APIs)
  - Rate-limits based on user subscription plans
  - Rate-limits based on token-bucket algorithm
  - Fine-grained rate-limits
    [configured via policies UI or yaml](https://docs.fluxninja.com/reference/cloud-ui/policies/policy-creation)
- Prioritizing requests based on custom labels (e.g. free user vs paid user)
- Enforcing adaptive rate-limits based on concurrency and available system
  capacity
- Managing load on your databases or self-hosted services such as Mistral,
  CodeLlama, etc.
- Caching API responses to avoid high API or Cloud cost and improve time to
  response
- Updating rate-limiting policies from UI without changing the code
- Monitoring workload for your internal or external services

Are we missing your use case for FluxNinja Aperture?
[Share with us on Discord](https://discord.gg/U3N3fCZEPm)

## Usage

### Install SDK

Run the command below to install the SDK:

```bash
npm install @fluxninja/aperture-js
```

### Create Aperture Client

The next step is to create an Aperture Client instance, for which, the address
of the organization created in Aperture Cloud and API key are needed. You can
locate both these details by clicking on the Aperture tab in the sidebar menu of
Aperture Cloud.

```typescript
import { ApertureClient } from "@fluxninja/aperture-js";

// Create aperture client
export const apertureClient = new ApertureClient({
  address: "ORGANIZATION.app.fluxninja.com:443",
  apiKey: "API_KEY",
});
```

### Flow Functionality

The created instance can then be used to start a flow:

```typescript
async function handleRequestRateLimit(req: Request, res: Response) {
  // Start a flow by passing control point and business labels
  const flow = await apertureClient.startFlow("awesomeFeature", {
    labels: {
      limit_key: "some_user_id",
    },
    grpcCallOptions: {
      deadline: Date.now() + 300, // ms
    },
  });

  if (flow.shouldRun()) {
    // Add business logic to process incoming request
    console.log("Request accepted. Processing...");
    const resString = "foo";
    res.send({ message: resString });
  } else {
    console.log("Request rate-limited. Try again later.");
    // Handle flow rejection
    flow.setStatus(FlowStatus.Error);
    res.status(429).send({ message: "Too many requests" });
  }

  flow.end();
}
```

The above code snippet is making `startFlow` calls to Aperture. For this call,
it is important to specify the control point (`awesomeFeature` in the example)
and business labels that will be aligned with the policy created in Aperture
Cloud. For request prioritization use cases, it's important to set a higher gRPC
deadline. This parameter specifies the maximum duration a request can remain in
the queue. For each flow that is started, a `shouldRun` decision is made,
determining whether to allow the request into the system or to rate limit it. In
this example, we only see log returns, but in a production environment, actual
business logic can be executed when a request is allowed. It is important to
make the `end` call made after processing each request, to send telemetry data
that would provide granular visibility for each flow.

For more context on using the Aperture JavaScript SDK to set feature control
points, refer to the [example app][example] available in the repository.

[example]: https://github.com/fluxninja/aperture-js/tree/main/example

# API Reference

# @fluxninja/aperture-js

## Table of contents

### Enumerations

- [FlowStatus](docs/enums/FlowStatus.md)
- [LookupStatus](docs/enums/LookupStatus.md)

### Classes

- [ApertureClient](docs/classes/ApertureClient.md)

### Interfaces

- [CacheEntry](docs/interfaces/CacheEntry.md)
- [Flow](docs/interfaces/Flow.md)
- [FlowParams](docs/interfaces/FlowParams.md)
- [KeyDeleteResponse](docs/interfaces/KeyDeleteResponse.md)
- [KeyLookupResponse](docs/interfaces/KeyLookupResponse.md)
- [KeyUpsertResponse](docs/interfaces/KeyUpsertResponse.md)