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

pocket-rest-lib

v1.0.4

Published

A library for making RESTful API requests in a structured manner much like PocketBase

Downloads

49

Readme

npm version npm downloads

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?

  1. Saves development time by handling common API tasks.
  2. Reduces the need for repetitive code.
  3. No need to integrate additional HTTP or WebSocket libraries.
  4. Lightweight and easy to integrate.
  5. 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
  6. Another difference with the PocketBase's original is constructing the filepath from filename and recordId. Refer to this: Filepath Generation

Table of Contents

  1. Pocket REST Lib
  2. Features
  3. Installation
  4. Setup and Usage
  5. API Reference
  6. Requirements
  7. Why Use PocketBase API Wrapper?
  8. Contributions
  9. Acknowledgments

Features

  • Simplified CRUD Operations: No need to write separate create, update, delete, or get 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 like Axios.
  • 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.