Service registration, retrieval, and lifecycle management within the Feathers application.
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);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"
});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");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");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
});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;/**
* 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[];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();
}
]
}
});