Skip to main content

ApinniEndpoint

The @ApinniEndpoint decorator annotates a controller method to define an API endpoint, specifying its path, HTTP method, and optional request/response types. It supports type inference through generics, decorator options, or method return types, following a defined priority for type resolution. The decorator integrates with the Apinni pipeline to generate type-safe API definitions for use with utility types like ApiRequest, ApiResponses etc.

Key Features
  • Type-safe endpoint definitions with TypeScript generics.
  • Flexible type resolution for requests and responses.
  • Multiple ways to define endpoint types and names

Syntax

Define an endpoint with the @ApinniEndpoint decorator, specifying the path, method, and optional request/response configurations.

Basic Syntax
@ApinniEndpoint<{
query: { type: QueryType; name: "GetUserQueryDto" },
request: { type: RequestType; name: "GetUserRequestDto" }
responses: {
200: { type: UserModelDto, name: 'GetUserResponseDto' },
403: { type: AuthErrorDto, name: 'AuthErrorDto' }
}
}>({
path: '/create-user',
method: 'POST',
query: { model: 'QueryType'; name: "GetUserQueryDto" },
request: { model: 'RequestType'; name: "GetUserRequestDto" }
responses: {
200: { model: 'UserModelDto', name: 'GetUserResponseDto' },
403: { model: 'AuthErrorDto', name: 'AuthErrorDto' }
}
})

Options

PropertyTypeDescription
pathstringThe endpoint path (e.g., /:id). Supports type-safe parameterized paths.
methodGET | POST | PUT | PATCH | DELETEThe HTTP method for the endpoint.
query{ model: string, name?: string } | Array<string>Optional query type and custom name, or array of simple query param names.
request{ model: string, name?: string }Optional request type and custom name.
responses{ model: string, name?: string } | { [status: number]: { model: string, name?: string } }Response types, either single (status 200) or multiple (by status code).
tip

Use :param notation in path for route parameters. TypeScript ensures unique parameter names for type safety.

Generic Types

The decorator supports a generic type parameter interface:

EndpointShape Interface
interface EndpointShape {
query?: { type: unknown; name?: string };
request?: { type: unknown; name?: string };
responses?: { [status: number]: { type: unknown; name?: string } };
}

This allows explicit type definitions for queries, requests, and responses, along with expressions like User[].

Recommended approach

In this way you don't have to worry about incorrect types' name spelling, named imports or any other limitations related to a raw string names.

Type Resolution Priority

Types for requests and responses are resolved in this order:

  1. Generic Types: Defined via <EndpointShape> (e.g., { request: { type: UserRequest } }).
  2. Decorator Options: Specified in query.model, request.model or responses.model.
  3. Method Return Type: Inferred for responses if no responses option is provided.
warning

Ensure model references exist in your TypeScript project to avoid incorrect type resolutions.

Examples

Below are examples demonstrating common use cases for @ApinniEndpoint. Use the tabs to explore different configurations.

Define a simple GET endpoint with an inferred response type.

Basic Endpoint
import { ApinniController, ApinniEndpoint } from '@apinni/client-ts';

@ApinniController({ path: '/users' })
class UserController {
@ApinniEndpoint({ path: '/:id', method: 'GET' })
getUserById() {
return { id: '123', name: 'User' };
}
}
example
  ["/users/:id"]: {
GET: {
query: never;
request: never;
responses: {
200: GetUsersByIdResponse; /* { id: string; name: string } */
}
}
}
Try It Out

Explore these examples in a live TypeScript environment: CodeSandbox Link.

Usage Notes

  • Type References: Ensure model references a type defined in your TypeScript project.
  • Single Response: A single responses object is automatically assigned to status 200.
  • Validation: Validate generics and model references to prevent generation issues.
info

For advanced use cases, check the Apinni API Reference or contact the Apinni community.