npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

api-tools-ts

v2.0.1

Published

A modern, type-safe, light-weight library to help you create APIs quickly using Express.js, written in TypeScript

Readme

API-Tools-TS

A modern, type-safe, light-weight library to help you create APIs quickly using Express.js, written in TypeScript.

npm version TypeScript

🚀 Features

  • Type-safe: Full TypeScript support with comprehensive type definitions
  • Easy to use: Simplified Express.js API for beginners
  • Flexible: Support for middleware, parameter validation, and bulk route registration
  • Modern: Promise-based with async/await support
  • Secure: Built-in security middlewares (helmet, cors)
  • Configurable: Extensive configuration options

📦 Installation

npm install api-tools-ts

🏃‍♂️ Quick Start

TypeScript

import { APIController } from "api-tools-ts";

const api = new APIController("/api/v1", {
  port: 3000,
  useDefaultMiddlewares: true
});

api.addEndpoint("/", "get", (req, res) => {
  res.json({ message: "Hello World!" });
});

await api.startServer();

JavaScript

const { APIController } = require("api-tools-ts");

const api = new APIController("/api/v1");

api.addEndpoint("/", "get", (req, res) => {
  res.json({ message: "Hello World!" });
});

api.startServer();

📖 Examples

Basic API with Multiple Endpoints

import { APIController } from "api-tools-ts";

const api = new APIController("/api/v1");

// Simple GET endpoint
api.addEndpoint("/", "get", (req, res) => {
  res.json({ message: "Welcome to the API!" });
});

// Parameterized endpoint
api.addEndpoint("/users/:id", "get", (req, res) => {
  const userId = req.params.id;
  res.json({ userId, message: `User ${userId} profile` });
});

await api.startServer();

Multiple HTTP Methods on Single Endpoint

import { APIController } from "api-tools-ts";

const api = new APIController("/api/v1");

const getUsers = (req, res) => {
  res.json({ users: [], message: "All users" });
};

const createUser = (req, res) => {
  res.status(201).json({ message: "User created", user: req.body });
};

const deleteUser = (req, res) => {
  res.json({ message: "User deleted" });
};

api.addMultipleMethods("/users", ["get", "post", "delete"], [getUsers, createUser, deleteUser]);

await api.startServer();

Bulk Route Registration

import { APIController, RouteDefinition } from "api-tools-ts";

const api = new APIController("/api/v1");

const routes: RouteDefinition[] = [
  {
    path: "/users",
    method: "get",
    handler: (req, res) => res.json({ users: [] })
  },
  {
    path: "/users",
    method: "post",
    handler: (req, res) => res.status(201).json({ user: req.body })
  },
  {
    path: "/health",
    method: ["get", "head"],
    handler: [(req, res) => res.json({ status: "ok" }), (req, res) => res.status(200).end()]
  }
];

api.addRoutes(routes);
await api.startServer();

Custom Middlewares

import { APIController } from "api-tools-ts";

const api = new APIController("/api/v1");

// Add custom middleware
api.addMiddleware("logger", (req, res, next) => {
  console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
  next();
});

// Add authentication middleware
api.addMiddleware("auth", (req, res, next) => {
  const token = req.headers.authorization;
  if (!token) {
    return res.status(401).json({ error: "Token required" });
  }
  next();
});

api.addEndpoint("/protected", "get", (req, res) => {
  res.json({ message: "This is a protected route" });
});

await api.startServer();

Parameter Validation

import { APIController } from "api-tools-ts";

const api = new APIController("/api/v1");

// Add parameter validation
api.addParamChecker("id", (req, res, next, value) => {
  const id = parseInt(value);
  if (isNaN(id) || id <= 0) {
    return res.status(400).json({ error: "Invalid ID parameter" });
  }
  req.params.id = id.toString(); // Normalize the parameter
  next();
});

api.addEndpoint("/users/:id", "get", (req, res) => {
  res.json({ userId: req.params.id, message: "Valid user ID" });
});

await api.startServer();

Advanced Configuration

import { APIController } from "api-tools-ts";

const api = new APIController("/api/v1", {
  port: 8080,
  hostname: "0.0.0.0",
  useDefaultMiddlewares: true,
  cors: {
    origin: ["http://localhost:3000", "https://yourdomain.com"],
    credentials: true
  },
  helmet: {
    contentSecurityPolicy: false
  },
  morgan: "combined",
  jsonLimit: "50mb"
});

await api.startServer();

Error Handling

import { APIController, ControllerErrors, Errors } from "api-tools-ts";

const api = new APIController("/api/v1");

api.addEndpoint("/error-demo", "get", (req, res) => {
  // The library will automatically handle ControllerErrors
  throw new ControllerErrors("Something went wrong", Errors.CONTROLLER_ERROR, {
    timestamp: Date.now(),
    endpoint: "/error-demo"
  });
});

await api.startServer();

Server Lifecycle Management

import { APIController } from "api-tools-ts";

const api = new APIController("/api/v1");

api.addEndpoint("/", "get", (req, res) => {
  res.json({ message: "Hello World!" });
});

// Start the server
await api.startServer();

// Get server information
console.log(api.getServerInfo());
// Output: { port: 3000, hostname: 'localhost', mainEndPoint: '/api/v1', isRunning: true }

// Check active connections
console.log(`Active connections: ${api.getActiveConnections()}`);

// Gracefully stop the server
await api.stopServer();

// Restart the server
await api.restartServer();

// Force stop (for emergencies)
api.forceStopServer();

Graceful Shutdown in Production

import { APIController } from "api-tools-ts";

const api = new APIController("/api/v1");

// Set up your routes
api.addEndpoint("/", "get", (req, res) => {
  res.json({ message: "API is running" });
});

await api.startServer();

// Handle graceful shutdown on process signals
process.on('SIGTERM', async () => {
  console.log('SIGTERM received, shutting down gracefully');
  try {
    await api.stopServer();
    process.exit(0);
  } catch (error) {
    console.error('Error during shutdown:', error);
    process.exit(1);
  }
});

process.on('SIGINT', async () => {
  console.log('SIGINT received, shutting down gracefully');
  try {
    await api.stopServer();
    process.exit(0);
  } catch (error) {
    console.error('Error during shutdown:', error);
    process.exit(1);
  }
});

🔧 API Reference

Constructor

new APIController(endpoint: string, config?: APIControllerConfig)

APIControllerConfig

interface APIControllerConfig {
  port?: number;                    // Default: 3000
  hostname?: string;                // Default: 'localhost'
  useDefaultMiddlewares?: boolean;  // Default: true
  cors?: cors.CorsOptions;          // CORS configuration
  helmet?: HelmetOptions;           // Helmet configuration
  morgan?: string | FormatFn;       // Morgan logging format
  jsonLimit?: string;               // JSON payload limit
  urlEncodedLimit?: string;         // URL encoded payload limit
}

Methods

Modern API (Recommended)

  • addEndpoint(path, method, callback, middlewares?) - Add a single endpoint
  • addMultipleMethods(path, methods, callbacks) - Add multiple methods to one path
  • addRoutes(routes) - Bulk register routes
  • addMiddleware(id, callback) - Add middleware
  • addParamChecker(param, callback) - Add parameter validation
  • startServer(config?) - Start the server
  • stopServer() - Stop the server gracefully
  • forceStopServer() - Force stop the server immediately
  • restartServer() - Restart the server
  • getServerInfo() - Get server status
  • getEndpoints() - Get all registered endpoints
  • getActiveConnections() - Get current connection count

Legacy API (Backward Compatible)

  • AddEndPoint() - Legacy version of addEndpoint
  • AddMultipleMethods() - Legacy version of addMultipleMethods
  • AddMiddleWare() - Legacy version of addMiddleware
  • AddParamChecker() - Legacy version of addParamChecker

🛡️ Default Middlewares

When useDefaultMiddlewares is true (default), the following middlewares are automatically applied:

  • Morgan: HTTP request logger
  • Helmet: Security headers
  • CORS: Cross-origin resource sharing
  • Express.json(): JSON body parser
  • Express.urlencoded(): URL encoded body parser

📝 Migration from v1.x

The library maintains backward compatibility, but we recommend migrating to the new API:

// Old way (still works)
api.AddEndPoint("/users", "get", callback);

// New way (recommended)
api.addEndpoint("/users", "get", callback);

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License

MIT License - see the LICENSE file for details.

📊 Changelog

v2.0.0

  • ✨ Modern async/await API
  • 🔒 Improved type safety
  • 🛡️ Better error handling
  • 📦 Bulk route registration
  • ⚙️ Advanced configuration options
  • 🔄 Backward compatibility maintained