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 🙏

© 2024 – Pkg Stats / Ryan Hefner

api-socket

v0.4.2

Published

- [What is api-socket](#what-is-api-socket) - [What is api-socket-client](#what-is-api-socket-client) - [Installation](#installation) - [Basic Usage](#basic-usage) - [Controllers](#controllers) - [Request Handlers](#request-handlers) - [C.R.U.D.

Downloads

20

Readme

⚠️ IMPORTANT: api-socket is still a work in progress. It is subject to constant and unnotified changes. Do not use this library until version 1.0.0.

What is api-socket

api-socket is a library for writing api servers using WebSocket instead of http. It is intended for apps that must be as responsive as possible. api-socket makes synchronizing the state of apps between the server and the clients as easy and robust as possible.

Some other great aspects:

  • Works with typescript out of the box
  • Works in Node.js and all modern browsers
  • Has built-in support for runtime type checking
  • Can be configured to use https for security

What is api-socket-client

api-socket-client is the client-side version of this library. It allows you to very easily communicate with the server created with api-socket.

Installation

To install the latest version of api-socket:

npm install api-socket

To install the latest version of api-socket-client for your client side code go to installation.

Basic Usage

Creating a simple api server

// server.ts
import { Api, request, z } from "api-socket";

// The api server is created with http protocol (still uses WebSocket)
// and we create the user controller.
const api = Api.protocol("http").controller("user", {
  login: request({
    // The input property defines the inputs and types that the login request handler takes.
    input: z.object({ email: z.string(), password: z.string() }),

    // The request handler is called whenever a client posts a login request.
    handler({ email, password }) {
      console.log(email, password);
      return "accessToken";
    },
  }),
});

// Starts the server on port 3000 and calls the callback once the server starts.
api.listen(3000, () => console.log("listening on port 3000!"));

// Export the api server type so we can use it in the client typescript code.
export type ApiServer = typeof api;

Creating a simple api client

// client.ts
import { ApiClient, createClient } from "api-socket-client";
import { ApiServer } from "./server";

// The client is created with the server's ip and an optional
// callback for when the client connects to the server.
const client = createClient<ApiServer>("http://localhost:3000", async () => {
  // We can post the login message to the server like this. This is
  // completely typesafe since we created the client with the ApiServer type.
  const response = await client.post("user", "login", {
    email: "email",
    password: "password",
  });

  console.log(response);
});

Controllers

Controllers are added to the server by

api.controller("name", {
  /* request handlers */
});

Request Handlers

All controllers have request handlers. They are the functions that are called when a client sends a request.

import { ..., request } from 'api-socket';

api.controller("name", {
  requestHandler: request({
    input: /* the request's input schema. */,
    handler() { ... } /* the method that is called when requested. */
  })
});

C.R.U.D. (Create, Read, Update, and Delete)

api-socket supports crud operations. To create a request handler for a specific crud operation simply prepend create, get, update, or delete to the name.

// server.ts
api.controller("user", {
  // This request handler would be in charge of creating users.
  create: request({ ... }),

  // This request handler would be in charge of getting the user's account.
  getAccount: request({ ... })
});

To send a crud request to the server simply do

// client.ts
const response = await client.create("user", { ... });
const response = await client.get("user", "account", { ... });

Services

Services are used for dependency injection.

An example service

import { ... , fail } from 'api-socket';

class AuthService {
  private accessToken?: string;

  constructor(accessToken?: string) {
    this.accessToken = accessToken;
  }

  assert(predicate: boolean) {
    if (!predicate) fail('Unauthorized');
  }
}

The service can be added to your api server

import { ..., scoped, Scope }

api.services([ scoped(AuthService, ({ accessToken }) => new AuthService(accessToken), Scope.request ) ]);

The service can be injected into a request handler

import { ..., request }

api.controller('user', {
  login: request({
    input: z.object({ ..., accessToken: z.string() }),

    handler({ ..., accessToken, inject }) {
      const auth = inject(AuthService, { accessToken });
      auth.assert(...);
      ...
    }
  })
});

Singleton Services

Singleton services are services that share the same instance throughout the entire server.

They can be added to your server

import { ..., singleton } from 'api-socket';

api.services([ singleton(YourService, new YourService()) ]);

Scoped Services

Scoped services are services that create a new instance for each scope.

There are two scopes a scoped service can have: Scope.controller and Scope.request. A service with Scope.controller will share the same instance within each individual controller, while a service with Scope.request is initialized per request. A scoped service has Scope.controller by default.

They can be added to your server

import { ..., scoped, Scope } from 'api-socket';

api.services([ scoped(YourService, () => new YourService(), /* optional: Scope.controller or Scope.request */) ]);

Api Service

You can inject your api into any request

handler({ ..., inject }) {
  const api = inject(Api);
}

The api service is mainly used to either broadcast messages to all clients or send a message to a room of clients.

const api = inject(Api);
api.broadcast("namespace", "message", /* optional args */ { ... });
api.send("room-id", "namespace", "message", /* optional args */ { ... });

Api is a singleton service.

Client Service

You can inject the client into any request

handler({ ..., inject }) {
  const client = inject(ApiClient);
}

The client service is mainly used to send messages to individual clients instead of rooms and to join the specific client to a room.

const client = inject(ApiClient);
client.send("namespace", "message", /* optional args */ { ... });

ApiClient is a request scoped service.