or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

application.mdhooks.mdindex.mdservice-interfaces.mdservices.md
tile.json

services.mddocs/

Service Management

Service registration, retrieval, and lifecycle management within the Feathers application.

Capabilities

Service Registration

Register services or sub-applications at specific paths within the Feathers application.

/**
 * Register a new service or a sub-app
 * @param path - The path for the service to register
 * @param service - The service object to register or another Feathers application to use as sub-app
 * @param options - The options for this service
 * @returns The application instance for chaining
 */
use<L extends keyof Services & string>(
  path: L,
  service: ServiceInterface | Application,
  options?: ServiceOptions<keyof Services[L]>
): this;

Usage Examples:

import { feathers, Service } from "@feathersjs/feathers";

const app = feathers();

// Register a service class
class MessageService implements Service {
  async find() {
    return [{ id: 1, text: "Hello" }];
  }
  
  async get(id: number) {
    return { id, text: "Hello" };
  }
}

app.use("messages", new MessageService());

// Register with options
app.use("todos", new TodoService(), {
  events: ["customEvent"],
  methods: ["find", "get", "create", "customMethod"]
});

// Register a sub-application
const subApp = feathers();
subApp.use("posts", new PostService());
app.use("api/v1", subApp);

Service Retrieval

Get registered services by their path to interact with them directly.

/**
 * Get the Feathers service instance for a path
 * @param path - The name of the service
 * @returns The enhanced Feathers service instance
 */
service<L extends keyof Services & string>(
  path: L
): FeathersService<this, Services[L]>;

Usage Examples:

// Get a service and use it
const messageService = app.service("messages");
const messages = await messageService.find();
const message = await messageService.get(1);

// Create new data
const newMessage = await messageService.create({
  text: "New message"
});

Service Unregistration

Remove services from the application and properly clean them up.

/**
 * Unregister an existing service
 * @param path - The name of the service to unregister
 * @returns Promise resolving to the unregistered service
 */
unuse<L extends keyof Services & string>(
  location: L
): Promise<FeathersService<this, Services[L]>>;

Usage Example:

// Unregister a service
const removedService = await app.unuse("messages");

Default Service Fallback

Provides a fallback mechanism when requesting non-existent services.

/**
 * Returns a fallback service instance that will be registered when no service was found
 * @param location - The path of the service
 * @returns A service interface (default implementation throws NotFound error)
 */
defaultService(location: string): ServiceInterface;

Usage Example:

// Override default service behavior
app.defaultService = function(location: string) {
  return {
    async get(id: string) {
      return { id, message: `Service ${location} not implemented` };
    }
  };
};

// Now accessing non-existent services won't throw errors
const result = await app.service("nonexistent").get("test");

Service Options

ServiceOptions Interface

Configuration options for service registration.

interface ServiceOptions<MethodTypes = string> {
  /**
   * A list of custom events that this service emits to clients
   */
  events?: string[] | readonly string[];
  
  /**
   * A list of service methods that should be available externally to clients
   */
  methods?: MethodTypes[] | readonly MethodTypes[];
  
  /**
   * Provide a full list of events that this service should emit to clients.
   * Unlike the events option, this will not be merged with the default events.
   */
  serviceEvents?: string[] | readonly string[];
  
  /**
   * Initial data to always add as route params to this service
   */
  routeParams?: { [key: string]: any };
}

Usage Examples:

// Service with custom events and methods
app.use("messages", new MessageService(), {
  events: ["messageRead", "messageArchived"],
  methods: ["find", "get", "create", "markAsRead", "archive"],
  routeParams: { tenant: "default" }
});

// Service with custom event list (not merged with defaults)  
app.use("notifications", new NotificationService(), {
  serviceEvents: ["sent", "delivered", "failed"] // Only these events, no defaults
});

Service Utilities

Service Wrapping

Internal utilities for enhancing services with Feathers functionality.

/**
 * Wrap a service with Feathers functionality (hooks, events, etc.)
 */
function wrapService(location: string, service: any, options: ServiceOptions): any;

/**
 * Get service options metadata from a wrapped service
 */
function getServiceOptions(service: any): ServiceOptions;

/**
 * Normalize and validate service options
 */
function normalizeServiceOptions(service: any, options?: ServiceOptions): ServiceOptions;

Service Constants

/**
 * Default service methods that Feathers recognizes
 */
const defaultServiceMethods: string[];

/**
 * Default service arguments mapping for each method
 */
const defaultServiceArguments: { [method: string]: string[] };

/**
 * Default events emitted by service methods
 */
const defaultServiceEvents: string[];

/**
 * Methods that cannot be used as custom service method names
 */
const protectedMethods: string[];

Enhanced Services

FeathersService Type

Services enhanced with Feathers functionality including hooks and events.

type FeathersService<A = FeathersApplication, S = Service> = S &
  ServiceAddons<A, S> &
  OptionalPick<ServiceHookOverloads<S>, keyof S>;

interface ServiceAddons<A = Application, S = Service> extends EventEmitter {
  id?: string;
  hooks(options: HookOptions<A, S>): this;
}

Usage Example:

const messageService = app.service("messages");

// Enhanced service has event functionality
messageService.on("created", (message, context) => {
  console.log("New message created:", message);
});

// Enhanced service has hook functionality
messageService.hooks({
  before: {
    create: [
      async (context) => {
        context.data.createdAt = new Date();
      }
    ]
  }
});