# api-socket

> - [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.

Latest version **0.4.2** (published 2022-04-21) · ISC license · 0 weekly downloads

## Install

```sh
npm install api-socket
pnpm add api-socket
yarn add api-socket
bun add api-socket
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.4.2 |
| Published | 2022-04-21 |
| First published | 2022-04-15 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 3 |
| Unpacked size | 11.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | noahgav |

## Links

- npm: https://www.npmjs.com/package/api-socket
- npm.io page: https://npm.io/package/api-socket

## Dependencies (3)

- [zod](https://npm.io/package/zod.md) ^3.14.4
- [socket.io](https://npm.io/package/socket.io.md) ^4.4.1
- [reflect-metadata](https://npm.io/package/reflect-metadata.md) ^0.1.13

## Recent versions

- 0.4.2 (latest) — 2022-04-21
- 0.4.1 — 2022-04-21
- 0.4.0 — 2022-04-21
- 0.3.2 — 2022-04-20
- 0.3.1 — 2022-04-20
- 0.3.0 — 2022-04-20
- 0.2.0 — 2022-04-18
- 0.1.4 — 2022-04-18
- 0.1.3 — 2022-04-18
- 0.1.2 — 2022-04-18
- 0.1.1 — 2022-04-18
- 0.1.0 — 2022-04-18
- 0.0.7 — 2022-04-16
- 0.0.6 — 2022-04-15
- 0.0.5 — 2022-04-15
- … 3 more at https://npm.io/package/api-socket/versions

## 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](#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. (Create, Read, Update, and Delete)](#crud-create-read-update-and-delete)
- [Services](#services)
  - [Singleton Services](#singleton-services)
  - [Scoped Services](#scoped-services)
  - [Api Service](#api-service)
  - [Client Service](#client-service)

# 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](https://www.npmjs.com/package/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:

```sh
npm install api-socket
```

To install the latest version of api-socket-client for your client side code go to [installation](https://www.npmjs.com/package/api-socket-client#installation).

# Basic Usage

Creating a simple api server

```typescript
// 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

```typescript
// 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

```typescript
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.

```typescript
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.

```typescript
// 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

```typescript
// 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

```typescript
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

```typescript
import { ..., scoped, Scope }

api.services([ scoped(AuthService, ({ accessToken }) => new AuthService(accessToken), Scope.request ) ]);
```

The service can be injected into a request handler

```typescript
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

```typescript
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

```typescript
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

```typescript
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.

```typescript
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

```typescript
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.

```typescript
const client = inject(ApiClient);
client.send("namespace", "message", /* optional args */ { ... });
```

ApiClient is a request scoped service.

---
_Source: https://npm.io/package/api-socket · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
