services

Organize TypeScript backend logic into reusable services with defineService and dependency injection.

Updated Aug 23, 2026
One-click install
npx skills add https://github.com/perimetre/ai-toolkit --skill services
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: services
Source: https://github.com/perimetre/ai-toolkit/tree/main/plugins/perimetre-apps/skills/services
Command: npx skills add https://github.com/perimetre/ai-toolkit --skill services

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

Decouple business logic from HTTP routes by organizing it into reusable, testable service modules that sit between routes/controllers and data sources.

Core Features & Use Cases

  • Define services with defineService to encapsulate domain logic and orchestration.
  • Support dependency injection via deps to compose services from data sources, APIs, and other services.
  • Return results as discriminated unions using an ok discriminator, allowing explicit success and error handling without throwing.
  • Keep routes thin by delegating business logic to services, enabling easy testing, reusability, and end-to-end workflows.

Quick Start

Define a new service using defineService, implement a getById method, and invoke it from a route to perform a business operation.

Frequently Asked Questions about services

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I decouple business logic from HTTP routes in a TypeScript backend?

To decouple business logic from HTTP routes in a TypeScript backend, you can encapsulate domain logic and orchestration into reusable service modules that sit between routes and data sources. This separation keeps routes thin and makes logic easily testable.

What is the best way to organize backend logic for dependency injection in TypeScript?

The best way to organize backend logic for dependency injection in TypeScript is by defining services that accept a context object for dependencies. This allows you to compose services from data sources, APIs, and other services without tight coupling.

How do I handle success and error results in TypeScript services without throwing exceptions?

To handle success and error results in TypeScript services without throwing exceptions, return results as discriminated unions using an ok discriminator. This pattern allows explicit success and error handling directly from the service output.

Can I compose multiple backend services together using tRPC and TypeScript?

Yes, you can compose multiple backend services together using tRPC and TypeScript. By defining services with a dedicated API and injecting dependencies, you can orchestrate end-to-end workflows by calling other services within a single service method.

Why should I keep my API routes thin and delegate logic to services?

You should keep API routes thin and delegate logic to services to achieve a clean separation of concerns across routes and data layers. This architecture enables easy testing, high reusability, and maintainable end-to-end workflows.

Do I need a specific API to define a service in my TypeScript backend architecture?

Yes, you need to use the defineService API to define a service in your TypeScript backend architecture. This API requires a context object for dependencies and structures your domain logic to sit between controllers and data sources.