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

unified-api

v1.0.15

Published

Easily create and call APIs in Typescript

Downloads

1,376

Readme

Unified API

Unified API lets you create APIs quickly and easily. No more creating two methods for one API route, no more writing the same boilerplate code over and over again. Just write one handler method and use that same method to both call and respond to that API route.

Designed to be easily unit testable (mongo-anywhere works well for unit testing).

Using Next.js? Use the unified-api-nextjs package to automatically use Next.js types and quickly connect your webserver to your API.

Usage

Creating endpoints

To get started, create a new subclass of ApiTemplate<TDependencies> and a type for your API's external dependencies, like so:

type TestDependencies = {
	testDependency: string; // Pretend we have to fetch this from our database
};

class TestApi extends ApiTemplate<TestDependencies> {
	constructor() {
		// First argument is the prefix for all API routes, second argument is a function that is called whenever a route throws an error.
		// API_PREFIX should be replaced by your API prefix (ex: /api/).
		const requestHelper = new RequestHelper(API_PREFIX, () => {});
		super(requestHelper, false);
		this.init(); // Init configures API routes so they are ready to be called.
	}
}

Then, create a field in your API class for each endpoint, like so:

class TestApi extends ApiTemplate<TestDependencies> {
	rootRoute = createRoute<[string, number], string, TestDependencies, {}>({
		isAuthorized: (req, res, deps, [name, number]) =>
			Promise.resolve({ authorized: true, authData: {} }),

		handler: (req, res, deps, authData, [name, number]) => {
			res.status(200).send(`Hello, ${name} ${number}!`);
		},
	});
}

createRoute is the function that creates an endpoint. It's generic parameters, in order, are:

  • The type of the arguments that the endpoint takes, as an array. Ex: [string, number]
  • The type of the return value of the endpoint. Ex: string
  • The type of the dependencies that the endpoint uses. This should be the same as the TDependency generic parameter you passed to ApiTemplate. Ex: TestDependencies
  • The type of the data that is fetched in the process of determining whether the request is authorized. Ex: undefined, {}

It takes an object with two fields: isAuthorized and handler.

isAuthorized is a function that determines whether the request is authorized. It takes the request, response, dependencies, and arguments provided by the API call. It should return a promise that resolves to an object with two fields: authorized and authData. authData is any data that was fetched in the process of determining whether the request is authorized.

handler is a function that handles the request. It takes the request, response, dependencies, authData, and arguments provided by the API call. Use res.status(code) and res.send(obj) to respond to API requests.

Responding to requests

Finally, create an subclass of ServerApi<TDependencies>, pass your API class and error logging mode (throw, log, or none) to the super constructor, and override the getDependencies method, like so:

class TestServerApi extends ServerApi<TestDependencies> {
	constructor() {
		super(new TestApi(), ErrorLogMode.None);
	}

	getDependencies() {
		return {
			testDependency: "test",
		};
	}
}

getDependencies must return an object of type TDependencies.

Connecting your API to a web server

To connect your web server to your ServerApi, call the handle method and pass in the request and the response objects, like so:

const serverApi = new TestServerApi();
await serverApi.handle(req, res); // await is optional

Calling your API

To call your API, create an instance of your ApiTemplate subclass and call the appropriate method, like so:

const clientApi = new TestApi();
await clientApi.requestHelper("Test", 1234); // await is optional

Unified API © 2024 by Decatur Robotics is licensed under the MIT license.