pocket-rest-lib
v1.0.4
Published
A library for making RESTful API requests in a structured manner much like PocketBase
Downloads
380
Maintainers
Readme
Pocket REST Lib
Pocket REST Lib is an NPM library designed to simplify API interactions through a structured and consistent way to perform CRUD operations and authentication with minimal effort. It is totally inspired by PocketBase's amazingly simple request mapping. It eliminates the need to manually design and call APIs, letting the developers focus on fast development.
While doing academic projects, I found it wasting to think on how to map the API requests every time I made some application. PocketBase's simplified mapping and fetching got me really fascinated. So, I thought why not just implement a REST mapping much like this one and integrate with my backend?
Why Use PocketBase API Wrapper?
- Saves development time by handling common API tasks.
- Reduces the need for repetitive code.
- No need to integrate additional HTTP or WebSocket libraries.
- Lightweight and easy to integrate.
- The key difference with PocketBase's original SDK is that this library, for realtime features, uses WebSocket, which is a full duplex communication protocol, instead of Server Sent Events, which only allows one sided communication from the server. Refer: Realtime
- Another difference with the PocketBase's original is constructing the filepath from filename and recordId. Refer to this: Filepath Generation
Table of Contents
- Pocket REST Lib
- Features
- Installation
- Setup and Usage
- API Reference
- Requirements
- Why Use PocketBase API Wrapper?
- Contributions
- Acknowledgments
Features
- Simplified CRUD Operations: No need to write separate
create
,update
,delete
, orget
functions. - Built-in Error Handling: Eliminates the hassle of writing repetitive
try-catch
blocks. - Native Fetch Support: Works with native
fetch
; no need for additional HTTP libraries likeAxios
. - Authentication Support: Built-in support for JWT-based authentication using
authWithPassword
. - Real-time Updates: Uses WebSocket for real-time communication, unlike PocketBase.
- Minimal Dependencies: Includes only the
jwt-decode
library as a dependency.
Installation
To install the library, run:
npm install pocket-rest-lib
Setup and Usage
1. Backend Setup
Your backend must follow the request mapping structure show in this documentation to integrate with this library. Refer to this Section: API Reference
2. Import the Library
import PocketRestLib from 'pocket-rest-lib';
3. Initialize the Client
const client = new PocketRestLib('https://your-backend-url.com');
4. Usage
Collection Management
You can manage a specific collection by calling the collection
method:
const users = client.collection('users');
CRUD Operations
The Collection
object provides methods to perform CRUD operations.
Create
await users.create({ username: 'john_doe', email: '[email protected]' });
Read One
const user = await users.getOne('12345');
Read List
const userList = await users.getList(1, 20, { filter: "verified=true" });
Update
await users.update('12345', { username: 'john_updated' });
Delete
await users.delete('12345');
Get Full List
Retrieve all records (paginated internally):
const allUsers = await users.getFullList();
Get First List Item
Retrieve the first item matching a filter:
const firstUser = await users.getFirstListItem("email='[email protected]'");
Authentication
Authenticate with a username and password:
const authResponse = await users.authWithPassword('[email protected]', 'securepassword');
Authentication tokens are automatically stored and reused for subsequent requests.
Real-time Subscriptions
My realtime implementation uses WebSocket connections unlike PocketBase's SSE. So, it's different.
Subscribe to real-time updates on a collection:
const subscription = users.subscribe();
subscription.onCreate((data) => {
console.log('Record created:', data);
});
subscription.onUpdate((data) => {
console.log('Record updated:', data);
});
subscription.onDelete((data) => {
console.log('Record deleted:', data);
});
To unsubscribe:
users.unsubscribe();
File Management
Generate file URLs for specific records:
const fileUrl = users.file('recordId', 'filename.jpg');
console.log(fileUrl); // Outputs: https://your-backend-url.com/api/files/users/recordId/filename.jpg
Methods
Collection Methods
| Method | Description |
|-----------------------------|-----------------------------------------------------|
| create(data, auth?)
| Create a new record. |
| update(id, data, auth?)
| Update a record by ID. |
| delete(id, auth?)
| Delete a record by ID. |
| getOne(id, options?, auth?)
| Retrieve a single record by ID. |
| getList(page, perPage, options?, auth?)
| Retrieve a paginated list of records. |
| getFullList(options?, auth?)
| Retrieve all records (paginated internally). |
| getFirstListItem(filter, options?, auth?)
| Retrieve the first matching record. |
| subscribe()
| Subscribe to real-time updates via WebSocket. |
| unsubscribe()
| Unsubscribe from WebSocket updates. |
| authWithPassword(identity, password)
| Authenticate using email and password. |
| file(recordId, filename)
| Generate a file URL for a specific record. |
Authentication Store Methods
| Method | Description |
|-----------------------------|-----------------------------------------------------|
| loadFromCookie(cookie, key?)
| Load authentication from a cookie. |
| exportToCookie(options?, key?)
| Export authentication to a cookie. |
| save(token, model)
| Save authentication token and model to storage. |
| clear()
| Clear authentication data from storage. |
CRUD Helper Functions
The crud
utility simplifies HTTP methods.
| Function | Description |
|--------------|-----------------------------------------------------|
| GET(url)
| Perform a GET request to the specified URL. |
| POST(url, body)
| Perform a POST request with a JSON or FormData body. |
| PATCH(url, body)
| Perform a PATCH request with a JSON or FormData body. |
| DELETE(url)
| Perform a DELETE request to the specified URL. |
Error Handling
Errors are logged to the console. To handle errors programmatically, you can modify the crud
functions or wrap calls in a try-catch
block.
Example Usage
import PocketRestLib from 'pocket-rest-lib';
const client = new PocketRestLib('https://your-backend-url.com');
const users = client.collection('users');
(async () => {
// Authenticate
const auth = await users.authWithPassword('[email protected]', 'adminpassword');
// Create a new user
await users.create({ username: 'new_user', email: '[email protected]' });
// Retrieve user list
const userList = await users.getList(1, 10, { sort: '-created' });
console.log(userList);
// Subscribe to real-time updates
const subscription = users.subscribe();
subscription.onCreate((data) => console.log('User created:', data));
})();
API Reference
Here's a detailed API mapping documentation. This is pretty much similar to PocketBase's:
Endpoints
GET /api/collections/:collectionName/records
Retrieve a paginated list of records from a specific collection.
Query Parameters
| Parameter | Type | Description | Default |
|----------------|---------|-----------------------------------------------------------------------------------------------|---------|
| page
| Number | The page (offset) of the paginated list. | 1
|
| perPage
| Number | Maximum number of records per page. | 30
|
| sort
| String | Sort order of the records. Use -
for DESC or +
(default) for ASC. | None |
| filter
| String | Apply filters to the records. Example: filter=(id='abc' && created>'2022-01-01')
. | None |
| expand
| String | Expand nested relations up to 6 levels. Example: expand=relField1,relField2.subRelField
. | None |
| fields
| String | Specify which fields to include in the response. Example: fields=*,expand.relField.name
. | All |
| skipTotal
| Boolean | Skip the total counts query for faster performance. | false
|
Supported Sort Fields
@random
id
username
email
emailVisibility
verified
created
updated
name
avatar
Example
GET /api/collections/users/records?page=1&perPage=10&sort=-created&filter=(verified=true)&expand=profile
GET /api/collections/:collectionName/records/:id
Retrieve a single record by its ID.
Path Parameters
| Parameter | Type | Description |
|------------------|--------|-------------------------------|
| collectionName
| String | The name of the collection. |
| id
| String | The ID of the record. |
Example
GET /api/collections/users/records/12345
POST /api/collections/:collectionName/records
Create a new record in a collection.
Path Parameters
| Parameter | Type | Description |
|------------------|--------|-------------------------------|
| collectionName
| String | The name of the collection. |
Body
Send a JSON object containing the data for the new record.
Example
POST /api/collections/users/records
Content-Type: application/json
{
"username": "john_doe",
"email": "[email protected]",
"verified": true
}
PATCH /api/collections/:collectionName/records/:id
Update an existing record in a collection.
Path Parameters
| Parameter | Type | Description |
|------------------|--------|-------------------------------|
| collectionName
| String | The name of the collection. |
| id
| String | The ID of the record. |
Body
Send a JSON object containing the fields to update.
Example
PATCH /api/collections/users/records/12345
Content-Type: application/json
{
"username": "john_updated"
}
DELETE /api/collections/:collectionName/records/:id
Delete a record from a collection by its ID.
Path Parameters
| Parameter | Type | Description |
|------------------|--------|-------------------------------|
| collectionName
| String | The name of the collection. |
| id
| String | The ID of the record. |
Example
DELETE /api/collections/users/records/12345
Query Parameters in Detail
Pagination
page
: Specifies the current page number (default: 1).perPage
: Specifies the number of records per page (default: 30).
Sorting
Use the sort
parameter to sort records by attributes. Prefix with -
for DESC or leave it empty for ASC.
Example:
?sort=-created,id
Filtering
Use the filter
parameter to filter records using logical operators.
Example:
?filter=(id='12345' && verified=true)
Expanding Relations
Use the expand
parameter to include related fields.
Example:
?expand=profile,profile.address
Field Selection
Use the fields
parameter to specify which fields to return.
Example:
?fields=*,profile.name,profile.email
Skip Total
Set skipTotal=true
to speed up queries by skipping total count calculations. This is ideal for cursor-based pagination.
Notes
- All endpoints adhere to JWT-based authentication.
- Use
expand
with caution for deep relations to prevent performance issues.
Requirements
- Your backend must follow PocketBase's request mapping structure and must implement filtering, expanding, and pagination that aligns with this library API References
- Use only JWT-based authentication
Contributions
Contributions are very much welcome! Feel free to open issues or submit pull requests
Acknowledgments
Inspired by the PocketBase ecosystem. Special thanks to developers who value simplicity and efficiency.