or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

application.mdauthentication.mderror-handling.mdindex.mdrest-transport.mdservices.mdsocketio-transport.md
tile.json

rest-transport.mddocs/

REST Transport

HTTP-based transport supporting multiple HTTP clients (fetch, axios, superagent) for traditional REST API communication with automatic request/response handling and URL generation.

Capabilities

REST Client Factory

Create REST transport configuration with support for multiple HTTP client libraries.

/**
 * Create REST client configuration
 * @param baseURL - Base URL for the API server (optional)
 * @returns Object with transport methods for different HTTP clients
 */
function rest(baseURL?: string): {
  fetch(connection: any, options?: any): TransportConnection;
  axios(connection: any, options?: any): TransportConnection;
  superagent(connection: any, options?: any): TransportConnection;
};

interface TransportConnection<Services = any> {
  (app: Application): void;
}

Usage Examples:

import feathers from "@feathersjs/client";
import { rest } from "@feathersjs/client";

const app = feathers();

// Configure with base URL
const restClient = rest("http://localhost:3030");

// Use with different HTTP clients
app.configure(restClient.fetch(fetch));
// OR
app.configure(restClient.axios(axios));
// OR  
app.configure(restClient.superagent(superagent));

Fetch Transport

Configure REST transport using the Fetch API (browser native or node-fetch).

/**
 * Configure Fetch API transport
 * @param connection - Fetch function (global fetch or node-fetch)
 * @param options - Optional fetch configuration
 * @returns Transport connection function
 */
fetch(connection: any, options?: any): TransportConnection;

Usage Examples:

// Browser environment (global fetch)
app.configure(rest("https://api.example.com").fetch(fetch));

// Node.js environment with node-fetch
import fetch from "node-fetch";
app.configure(rest("https://api.example.com").fetch(fetch));

// With custom options
app.configure(rest("https://api.example.com").fetch(fetch, {
  headers: {
    "User-Agent": "MyApp/1.0"
  },
  timeout: 10000
}));

Axios Transport

Configure REST transport using Axios HTTP client library.

/**
 * Configure Axios transport
 * @param connection - Axios instance or axios function
 * @param options - Optional axios configuration
 * @returns Transport connection function
 */
axios(connection: any, options?: any): TransportConnection;

Usage Examples:

import axios from "axios";

// Basic axios configuration
app.configure(rest("https://api.example.com").axios(axios));

// With custom axios instance
const axiosInstance = axios.create({
  timeout: 5000,
  headers: {
    "Content-Type": "application/json"
  }
});

app.configure(rest("https://api.example.com").axios(axiosInstance));

// With additional options
app.configure(rest("https://api.example.com").axios(axios, {
  responseType: "json"
}));

Superagent Transport

Configure REST transport using Superagent HTTP client library.

/**
 * Configure Superagent transport
 * @param connection - Superagent function
 * @param options - Optional superagent configuration
 * @returns Transport connection function
 */
superagent(connection: any, options?: any): TransportConnection;

Usage Examples:

import superagent from "superagent";

// Basic superagent configuration
app.configure(rest("https://api.example.com").superagent(superagent));

// With custom options
app.configure(rest("https://api.example.com").superagent(superagent, {
  timeout: 8000,
  retry: 2
}));

REST Service Implementation

REST services automatically handle HTTP method mapping and URL generation.

/**
 * REST service base class (internal implementation)
 * Automatically maps service methods to HTTP requests
 */
abstract class Base<T = any, D = Partial<T>, P extends Params = Params> {
  /** HTTP GET for find operation */
  find(params?: RestClientParams<P>): Promise<Paginated<T> | T[]>;
  
  /** HTTP GET for single resource */
  get(id: Id, params?: RestClientParams<P>): Promise<T>;
  
  /** HTTP POST for create operation */
  create(data: D, params?: RestClientParams<P>): Promise<T>;
  create(data: D[], params?: RestClientParams<P>): Promise<T[]>;
  
  /** HTTP PUT for complete replacement */
  update(id: NullableId, data: D, params?: RestClientParams<P>): Promise<T | T[]>;
  
  /** HTTP PATCH for partial update */
  patch(id: NullableId, data: Partial<D>, params?: RestClientParams<P>): Promise<T | T[]>;
  
  /** HTTP DELETE for removal */
  remove(id: NullableId, params?: RestClientParams<P>): Promise<T | T[]>;
  
  /** Register custom HTTP methods */
  methods(...names: string[]): this;
}

interface RestClientParams<P extends Params = Params> extends P {
  /** HTTP client connection options */
  connection?: any;
}

HTTP Method Mapping:

Service MethodHTTP MethodURL Pattern
find()GET/service
get(id)GET/service/:id
create(data)POST/service
update(id, data)PUT/service/:id
patch(id, data)PATCH/service/:id
remove(id)DELETE/service/:id

Usage Examples:

// All service operations map to HTTP requests automatically
const userService = app.service("users");

// GET /users
const users = await userService.find();

// GET /users/123
const user = await userService.get(123);

// POST /users
const newUser = await userService.create({
  name: "John Doe",
  email: "john@example.com"
});

// PUT /users/123
const updatedUser = await userService.update(123, {
  name: "John Smith",
  email: "johnsmith@example.com"
});

// PATCH /users/123
const patchedUser = await userService.patch(123, {
  name: "John Updated"
});

// DELETE /users/123
const removedUser = await userService.remove(123);

Query Parameters

REST transport automatically converts service params to URL query parameters.

Usage Examples:

// Query parameters are automatically converted to URL query string
const users = await userService.find({
  query: {
    active: true,
    $limit: 10,
    $skip: 20,
    $sort: { name: 1 }
  }
});
// Becomes: GET /users?active=true&$limit=10&$skip=20&$sort[name]=1

// Complex queries
const filteredUsers = await userService.find({
  query: {
    age: { $gte: 18, $lt: 65 },
    $or: [
      { role: "admin" },
      { role: "moderator" }
    ]
  }
});
// Becomes: GET /users?age[$gte]=18&age[$lt]=65&$or[0][role]=admin&$or[1][role]=moderator

Custom Methods

REST services support custom methods beyond standard CRUD operations.

/**
 * Register custom HTTP methods on the service
 * @param names - Array of method names to register
 * @returns Service instance for chaining
 */
methods(...names: string[]): this;

Usage Examples:

// Register custom methods
const userService = app.service("users");
userService.methods("resetPassword", "sendWelcomeEmail");

// Custom methods become available (implementation depends on server)
// These would map to custom HTTP endpoints
await userService.resetPassword({ userId: 123, token: "reset-token" });
await userService.sendWelcomeEmail({ userId: 123, template: "welcome" });

Request Headers and Options

Pass custom headers and connection options with REST requests.

Usage Examples:

// Custom headers and connection options
const result = await userService.find({
  query: { active: true },
  headers: {
    "X-Custom-Header": "value",
    "Authorization": "Bearer token"
  },
  connection: {
    // HTTP client specific options
    timeout: 10000,
    retry: 3
  }
});

// Connection-specific options (varies by HTTP client)
const axiosResult = await userService.create(userData, {
  connection: {
    timeout: 5000,
    responseType: "json",
    validateStatus: (status) => status < 500
  }
});

Error Handling

REST transport automatically converts HTTP errors to FeathersJS error types.

Usage Examples:

import { errors } from "@feathersjs/client";

try {
  const user = await userService.get(999);
} catch (error) {
  if (error instanceof errors.NotFound) {
    console.log("User not found");
  } else if (error instanceof errors.BadRequest) {
    console.log("Invalid request:", error.message);
  } else if (error instanceof errors.NotAuthenticated) {
    console.log("Authentication required");
  }
}

// HTTP status codes are mapped to FeathersJS errors:
// 400 -> BadRequest
// 401 -> NotAuthenticated  
// 403 -> Forbidden
// 404 -> NotFound
// 500 -> GeneralError
// etc.

Type Definitions

interface RestClientParams<P extends Params = Params> extends P {
  /** HTTP client connection options */
  connection?: {
    timeout?: number;
    headers?: Record<string, string>;
    [key: string]: any;
  };
}