Skip to content

Services and endpoints

Use legacy TypeScript decorators to replace service methods with Fetcher requests. Enable experimentalDecorators and emitDecoratorMetadata (matching this package's tsconfig); stage-3 decorators do not support this parameter-decorator contract. The package imports reflect-metadata itself.

Class and method decorators

FactoryDefaultsResult
api(basePath = '', metadata = {})metadata: Omit<ApiMetadata, 'basePath'>Class decorator, returns the same constructor after binding endpoint methods.
endpoint(method?, path?, metadata = {})Optional method/pathMethod decorator recording EndpointMetadata.
get, post, put, del, patch, head, optionspath = '', metadata: MethodEndpointMetadata = {}Method decorators selecting the corresponding HTTP method; DELETE is named del.

PathCapable provides optional path. EndpointMetadata extends ApiMetadata and adds optional path/method; MethodEndpointMetadata omits those two fields. To use TRACE, choose endpoint(HttpMethod.TRACE, path) subject to native Fetch restrictions; there is no exported trace decorator.

AutoGenerated is an Error whose message is 'Implementation will be generated automatically.'. autoGeneratedError(...ignored) returns a new instance, does not throw it. Place throw autoGeneratedError(...) in a typed placeholder method. Without successful @api binding it will actually throw; a return annotation alone cannot implement a request.

API metadata and precedence

Field on ApiMetadataResolution
basePath?: stringEndpoint truthy override, then API path, then empty.
fetcher?: string | FetcherEndpoint non-nullish override, then API; resolved through getFetcher.
headers? / urlParams?Client defaults (headers), API, endpoint, then bound argument/request values; headers case-insensitive.
timeout?: numberEndpoint defined value (including zero), API, then client default.
resultExtractor?Endpoint, API, then JsonResultExtractor.
returnType?Endpoint, API, then EndpointReturnType.RESULT.
attributes?API entries followed by endpoint entries, then argument attributes.

ApiMetadataCapable.apiMetadata enables instance configuration. At the first call of each method, buildRequestExecutor shallow-spreads instance metadata over decorator metadata and caches the executor on that instance by method name. Set instance metadata before calling the method; later replacing metadata is not a supported live reconfiguration mechanism. Endpoint metadata still takes precedence. Shallow merging means an instance header object replaces the class header object before endpoint/request merging.

The default decorated return is parsed JSON, unlike Fetcher.get, which defaults to Response. For HEAD/204 or raw responses choose ResultExtractors.Response; for diagnostics use returnType: EndpointReturnType.EXCHANGE and annotate Promise<FetchExchange>. See execution for hooks and failures.

Complete example

ts
import { Fetcher } from '@ahoo-wang/fetcher';
import {
  api,
  get,
  path,
  autoGeneratedError,
} from '@ahoo-wang/fetcher-decorator';

type User = { id: string; name: string };
const client = new Fetcher({
  baseURL: 'https://api.example.com',
  timeout: 3000,
});
@api('/users', { fetcher: client })
class Users {
  @get('/{id}')
  find(@path('id') id: string): Promise<User> {
    throw autoGeneratedError(id);
  }
}
const users = new Users();
// Requires a service returning JSON at https://api.example.com/users/1.
async function loadUser() {
  return await users.find('1');
}
void loadUser;

Public symbols and source

SymbolImplementation
ApiMetadataapiDecorator.ts:40
ApiMetadataCapableapiDecorator.ts:83
apiapiDecorator.ts:228
PathCapableendpointDecorator.ts:5
EndpointMetadataendpointDecorator.ts:21
MethodEndpointMetadataendpointDecorator.ts:33
endpointendpointDecorator.ts:59
getendpointDecorator.ts:101
postendpointDecorator.ts:126
putendpointDecorator.ts:151
delendpointDecorator.ts:176
patchendpointDecorator.ts:201
headendpointDecorator.ts:229
optionsendpointDecorator.ts:254
AutoGeneratedgenerated.ts:25
autoGeneratedErrorgenerated.ts:41

Package index

Released under the Apache License 2.0.