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.