https://github.com/copyleftdev/api-metering-libary
Science Score: 13.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
○CITATION.cff file
-
✓codemeta.json file
Found codemeta.json file -
○.zenodo.json file
-
○DOI references
-
○Academic publication links
-
○Academic email domains
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (6.7%) to scientific vocabulary
Repository
Basic Info
- Host: GitHub
- Owner: copyleftdev
- License: mit
- Language: TypeScript
- Default Branch: main
- Size: 0 Bytes
Statistics
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
- Releases: 0
Metadata Files
README.md
API Metering Library for Stripe
A TypeScript library for metering API calls with Stripe's usage-based billing capabilities. This library provides a reusable, framework-agnostic solution for tracking API usage and reporting it to Stripe for billing purposes.
Architecture
```mermaid
classDiagram
%% Interfaces
class IMeteringStrategy {
<
%% Main Classes
class MeteringService {
-strategy: IMeteringStrategy
+recordApiCall(customerId: string, usageValue?: number, apiEndpoint?: string) Promise~void~
+dispose() Promise~void~
}
class MeteringServiceFactory {
<<static>>
+createService(config: MeteringServiceConfig) MeteringService
}
%% Strategies
class BatchedUsageRecordStrategy {
-stripeClient: Stripe
-batches: Map~string, UsageRecord[]~
-intervalId: NodeJS.Timeout
+recordUsage(customerId: string, usageValue: number) Promise~void~
+dispose() Promise~void~
-flushAllBatches() Promise~void~
-flushBatch(batch: UsageRecord[]) Promise~void~
}
class ImmediateMeterEventStrategy {
-stripeClient: Stripe
-meterEventName: string
-idempotencyKeyPrefix: string
+recordUsage(customerId: string, usageValue: number, context?: any) Promise~void~
+dispose() Promise~void~
}
%% Error Classes
class MeteringError {
+name: string
+message: string
}
class ConfigurationError {
+name: string
+message: string
}
class StripeApiError {
+name: string
+message: string
+stripeCode: string
}
%% Relationships
MeteringService --> IMeteringStrategy : uses
MeteringServiceFactory ..> MeteringService : creates
BatchedUsageRecordStrategy ..|> IMeteringStrategy : implements
ImmediateMeterEventStrategy ..|> IMeteringStrategy : implements
MeteringError <|-- ConfigurationError : extends
MeteringError <|-- StripeApiError : extends
```
Features
- Framework-agnostic: Works with any JavaScript/TypeScript backend
- Multiple reporting strategies:
- Immediate: Report each API call to Stripe immediately as a meter event
- Batched: Accumulate API calls and report them in batches as usage records
- Type-safe with comprehensive TypeScript definitions
- Built using best practices for code reusability and maintainability
- Defensive programming techniques to handle errors gracefully
Installation
bash
npm install api-metering-library stripe
Quick Start
```typescript import { MeteringServiceFactory } from 'api-metering-library';
// Create a metering service with the immediate strategy const meteringService = MeteringServiceFactory.createService({ stripeApiKey: 'sktestyourstripekey', strategyType: 'immediate', meterEventName: 'api_call' });
// Use the service to record API calls async function handleApiRequest(req, res) { const customerId = req.headers['x-customer-id'];
try { // Record the API call await meteringService.recordApiCall(customerId);
// Process the API request...
res.send({ success: true });
} catch (error) { console.error('Error processing API request:', error); res.status(500).send({ error: 'An error occurred' }); } } ```
Usage Examples
Setting Up with Immediate Reporting Strategy
```typescript import { MeteringServiceFactory } from 'api-metering-library';
const meteringService = MeteringServiceFactory.createService({ stripeApiKey: process.env.STRIPESECRETKEY || '', strategyType: 'immediate', meterEventName: 'api_call', idempotencyKeyPrefix: 'my-api' });
// Record an API call with default usage value (1) await meteringService.recordApiCall('cus_customer123');
// Record an API call with custom usage value and endpoint information await meteringService.recordApiCall('cus_customer123', 5, '/api/data/query'); ```
Setting Up with Batched Reporting Strategy
```typescript import { MeteringServiceFactory } from 'api-metering-library';
const meteringService = MeteringServiceFactory.createService({ stripeApiKey: process.env.STRIPESECRETKEY || '', strategyType: 'batched', batchIntervalMs: 30000, // 30 seconds maxBatchSize: 50, flushOnDispose: true });
// Record multiple API calls await meteringService.recordApiCall('cuscustomer123'); await meteringService.recordApiCall('cuscustomer456', 3);
// When shutting down your application, dispose the service to ensure all pending usage is reported process.on('SIGTERM', async () => { await meteringService.dispose(); process.exit(0); }); ```
Express.js Middleware Example
```typescript import express from 'express'; import { MeteringServiceFactory } from 'api-metering-library';
const app = express(); const meteringService = MeteringServiceFactory.createService({ stripeApiKey: process.env.STRIPESECRETKEY || '', strategyType: 'immediate', meterEventName: 'api_call' });
// Middleware to meter all API calls app.use(async (req, res, next) => { const customerId = req.headers['x-customer-id'] as string;
if (customerId) { try { await meteringService.recordApiCall(customerId, 1, req.path); } catch (error) { console.error('Error recording API usage:', error); // Continue processing the request even if metering fails } }
next(); });
app.get('/api/data', (req, res) => { res.json({ message: 'This API call was metered' }); });
app.listen(3000, () => { console.log('Server running on port 3000'); }); ```
API Reference
MeteringServiceFactory
The factory class used to create instances of the MeteringService.
createService(config: MeteringServiceConfig): MeteringService
Creates a new MeteringService instance with the specified configuration.
MeteringService
The main service class for recording API usage.
recordApiCall(customerId: string, usageValue?: number, apiEndpoint?: string): Promise<void>
Records an API call for the specified customer.
customerId: The ID of the customer making the API callusageValue: The amount of usage to record (defaults to 1)apiEndpoint: Optional endpoint information for context
dispose(): Promise<void>
Disposes of the service, cleaning up any resources and ensuring all pending usage is reported (for batched strategies).
Configuration Types
ImmediateMeterEventConfig
Configuration for the immediate meter event strategy:
stripeApiKey: Stripe API key (secret key) used for authenticationstrategyType: Must be 'immediate'meterEventName: The name of the meter event that will be reported to StripeidempotencyKeyPrefix(optional): Prefix for generating idempotency keys
BatchedUsageRecordConfig
Configuration for the batched usage record strategy:
stripeApiKey: Stripe API key (secret key) used for authenticationstrategyType: Must be 'batched'batchIntervalMs(optional): The interval in milliseconds at which batched usage records will be sent to Stripe (default: 60000)flushOnDispose(optional): Whether to flush any pending usage records when the service is disposed (default: true)maxBatchSize(optional): Maximum number of usage records to accumulate before forcing a flush (default: 100)
Error Handling
The library provides custom error types for better error handling:
MeteringError: Base error class for all errors from the libraryConfigurationError: Error related to invalid configurationStripeApiError: Error communicating with the Stripe APIInvalidInputError: Error related to invalid input parametersDependencyError: Error related to missing dependencies
Example of handling errors:
```typescript import { MeteringServiceFactory, StripeApiError } from 'api-metering-library';
try {
await meteringService.recordApiCall(customerId);
} catch (error) {
if (error instanceof StripeApiError) {
console.error(Stripe API error (${error.stripeCode}): ${error.message});
} else {
console.error('Error recording API call:', error);
}
}
```
Requirements
- Node.js >= 14
- Stripe account with metered billing configured
License
MIT
Owner
- Name: Donald Johnson
- Login: copyleftdev
- Kind: user
- Location: Los Angeles
- Repositories: 39
- Profile: https://github.com/copyleftdev
GitHub Events
Total
- Watch event: 1
- Push event: 4
- Create event: 2
Last Year
- Watch event: 1
- Push event: 4
- Create event: 2
Dependencies
- actions/checkout v3 composite
- actions/setup-node v3 composite
- codecov/codecov-action v3 composite
- actions/checkout v3 composite
- actions/setup-node v3 composite
- softprops/action-gh-release v1 composite
- 395 dependencies
- @types/jest ^29.5.3 development
- @types/node ^20.5.0 development
- @typescript-eslint/eslint-plugin ^6.4.0 development
- @typescript-eslint/parser ^6.4.0 development
- eslint ^8.47.0 development
- eslint-config-prettier ^9.0.0 development
- jest ^29.6.2 development
- prettier ^3.0.2 development
- ts-jest ^29.1.1 development
- ts-node ^10.9.1 development
- tslib ^2.6.1 development
- typescript ^5.1.6 development
- stripe ^14.0.0