@ticatec/app-data-service
v2.0.0
Published
This package provides a set of classes for handling data operations via HTTP requests. They are built in a hierarchical structure, with BaseDataService as the foundation, and CommonDataService, PagingDataService, and FullListDataService extending its func
Readme
Application Data Service
A TypeScript library providing a hierarchical set of classes for handling data operations via HTTP requests. Built with a foundation of BaseDataService and specialized services for common data operations including CRUD, full list retrieval, and paginated search functionality.
⚠️ v2.0 Breaking Changes
Version 2.0.0 is now ESM-only, which is a breaking change:
- ESM Only: No longer supports CommonJS
require() - Node.js Requirement: Node.js 12.20+ or environments with ESM support
- Peer Dependencies:
@ticatec/restful_service_apiis now a peer dependency and must be installed separately
If you require CommonJS support, please continue using v1.x:
npm install @ticatec/app-data-service@1中文 | English
Installation
npm install @ticatec/app-data-servicePrerequisites
This library requires a REST service implementation. The recommended implementation is:
npm install @ticatec/axios-restful-serviceQuick Start
import { BaseDataService, FullListDataService } from '@ticatec/app-data-service';
import RestService from '@ticatec/axios-restful-service';
// Configure the REST proxy
const restService = new RestService('https://api.example.com');
BaseDataService.setProxy(restService);
// Create a service for your data
class UserService extends FullListDataService {
constructor() {
super('/users');
}
}
const userService = new UserService();
const users = await userService.getList();Architecture Overview
The library follows a hierarchical architecture:
BaseDataService (Abstract)
├── CommonDataService (Abstract)
├── FullListDataService (Concrete)
└── PagingDataService (Concrete)- BaseDataService: Foundation class providing HTTP methods and proxy management
- CommonDataService: Adds CRUD operations with URL-based endpoints
- FullListDataService: Specialized for retrieving complete lists
- PagingDataService: Adds pagination and search capabilities
API Reference
BaseDataService
Abstract base class providing foundational HTTP request methods and static proxy management.
Static Methods
setProxy(value: RestService): void
Configures the HTTP client proxy for all data service instances.
import RestService from '@ticatec/axios-restful-service';
const restService = new RestService('https://api.example.com');
BaseDataService.setProxy(restService);Protected Methods
get service(): RestService
Getter for accessing the configured REST service proxy.
getService(): RestService
Alternative method for accessing the REST service proxy.
async get(url: string, params?: any, dataProcessor?: any): Promise<any>
Sends an HTTP GET request.
- url: The endpoint URL
- params: Optional query parameters
- dataProcessor: Optional response transformation function
async post(url: string, data?: any, options?: RestfulOptions): Promise<any>
Sends an HTTP POST request with JSON data.
- url: The endpoint URL
- data: The data to send in the request body (will be JSON encoded)
- options: Optional request configuration (headers, params, etc.)
async put(url: string, data?: any, options?: RestfulOptions): Promise<any>
Sends an HTTP PUT request with JSON data.
- url: The endpoint URL
- data: The data to send in the request body (will be JSON encoded)
- options: Optional request configuration (headers, params, etc.)
async del(url: string, data?: any, options?: RestfulOptions): Promise<any>
Sends an HTTP DELETE request.
- url: The endpoint URL
- data: Optional data to send in the request body (will be JSON encoded)
- options: Optional request configuration (headers, params, etc.)
CommonDataService
Abstract class extending BaseDataService with CRUD operations for URL-based endpoints.
Constructor
constructor(url: string)
Initializes the service with a base URL endpoint.
class UserService extends CommonDataService {
constructor() {
super('/users');
}
}Methods
save(data: any, isNew: boolean): Promise<any>
Saves data using POST for new entries or PUT for updates.
- data: The data to save
- isNew:
truefor POST (create),falsefor PUT (update)
// Create new user
await userService.save({ name: 'John Doe', email: '[email protected]' }, true);
// Update existing user
await userService.save({ id: 1, name: 'John Smith' }, false);remove(item: any): Promise<any>
Removes a data entry using DELETE request.
await userService.remove({ id: 1 });Protected Methods
getDeleteUrl(item: any): string
Returns the deletion URL for an item. Override to customize delete URL generation.
class UserService extends CommonDataService {
protected getDeleteUrl(item: any): string {
return `${this.url}/${item.id}`;
}
}FullListDataService
Concrete class for retrieving complete lists of data without pagination.
Methods
getList(params?: any): Promise<Array<any>>
Retrieves the complete list of data items.
- params: Optional query parameters for filtering
class ProductService extends FullListDataService {
constructor() {
super('/products');
}
}
const productService = new ProductService();
// Get all products
const allProducts = await productService.getList();
// Get filtered products
const electronics = await productService.getList({ category: 'electronics' });PagingDataService
Concrete class providing paginated search functionality. Automatically purges null/undefined values from search criteria using utils.objectPurge().
Methods
async search(criteria: any): Promise<PaginationList>
Searches for data with pagination support.
- criteria: Search criteria and pagination parameters
- pageNo: Current page number (starts from 1)
- Other search filters as needed
const results = await orderService.search({
status: 'pending',
pageNo: 1,
sortBy: 'createdAt',
sortOrder: 'desc'
});Protected Methods
buildSearchResult(result: any): PaginationList
Constructs pagination results from API response. By default, returns the result as-is. Override this method if your API returns a different format.
The PaginationList interface should contain:
- count: Total number of records (required)
- list: Array of data items (required)
- pageNo: Current page number (optional)
- pages: Total number of pages (optional)
- hasMore: Boolean indicating if there are more pages (optional)
class OrderService extends PagingDataService {
protected buildSearchResult(result: any): PaginationList {
// If API returns different format, transform it here
return {
count: result.totalRecords,
pageNo: result.currentPage,
pages: result.totalPages,
hasMore: result.currentPage < result.totalPages,
list: result.data
};
}
}Usage Examples
Basic CRUD Operations
import { CommonDataService, BaseDataService } from '@ticatec/app-data-service';
import RestService from '@ticatec/axios-restful-service';
// Setup
BaseDataService.setProxy(new RestService('https://api.example.com'));
class UserService extends CommonDataService {
constructor() {
super('/users');
}
protected getDeleteUrl(item: any): string {
return `${this.url}/${item.id}`;
}
}
const userService = new UserService();
// Create
const newUser = await userService.save({
name: 'John Doe',
email: '[email protected]'
}, true);
// Update
const updatedUser = await userService.save({
id: newUser.id,
name: 'John Smith'
}, false);
// Delete
await userService.remove({ id: newUser.id });Full List Retrieval
import { FullListDataService } from '@ticatec/app-data-service';
class CategoryService extends FullListDataService {
constructor() {
super('/categories');
}
}
const categoryService = new CategoryService();
const categories = await categoryService.getList();
const activeCategories = await categoryService.getList({ active: true });Paginated Search
import { PagingDataService } from '@ticatec/app-data-service';
import type PaginationList from '@ticatec/app-data-service/PaginationList';
class OrderService extends PagingDataService {
constructor() {
super('/orders');
}
protected buildSearchResult(result: any): PaginationList {
// Transform API response to match PaginationList interface
return {
list: result.items,
count: result.totalCount,
pageNo: result.page,
pages: Math.ceil(result.totalCount / result.pageSize),
hasMore: result.page * result.pageSize < result.totalCount
};
}
}
const orderService = new OrderService();
const paginatedOrders = await orderService.search({
status: 'pending',
customerName: 'John',
pageNo: 1
});
console.log(`Found ${paginatedOrders.count} orders`);
console.log(`Page ${paginatedOrders.pages} total, has more: ${paginatedOrders.hasMore}`);
paginatedOrders.list.forEach(order => console.log(order));Advanced Customization
class CustomUserService extends CommonDataService {
constructor() {
super('/users');
}
// Custom delete URL with ID
protected getDeleteUrl(item: any): string {
return `${this.url}/${item.id}`;
}
// Custom methods
async activateUser(userId: number): Promise<any> {
return this.put(`${this.url}/${userId}/activate`);
}
async getUserProfile(userId: number): Promise<any> {
return this.get(`${this.url}/${userId}/profile`);
}
}Configuration
REST Service Configuration
The library requires a REST service implementation that conforms to the RestService interface. The recommended implementation is @ticatec/axios-restful-service:
import RestService from '@ticatec/axios-restful-service';
const restService = new RestService('https://api.example.com', {
timeout: 10000,
headers: {
'Authorization': 'Bearer your-token',
'Content-Type': 'application/json'
}
});
BaseDataService.setProxy(restService);Error Handling
Implement error handling in your REST service configuration or in your service consumers:
class UserService extends FullListDataService {
constructor() {
super('/users');
}
async getList(params?: any): Promise<Array<any>> {
try {
return await super.getList(params);
} catch (error) {
console.error('Failed to fetch users:', error);
throw new Error('Unable to retrieve user list');
}
}
}Dependencies
Required Dependencies
- @ticatec/enhanced-utils: Required for
PagingDataService(object utilities likeobjectPurge)
Peer Dependencies (must install separately)
- @ticatec/restful_service_api: Interface definitions for REST services (^0.5.0)
Recommended Installation
- @ticatec/axios-restful-service: Recommended REST service implementation
Complete installation:
npm install @ticatec/app-data-service
npm install @ticatec/restful_service_api @ticatec/axios-restful-serviceTypeScript Support
This library is written in TypeScript and includes full type definitions. All classes and methods are properly typed for enhanced development experience.
License
MIT License - see the LICENSE file for details.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
Support
For issues, questions, or contributions:
- Email: [email protected]
- GitHub: https://github.com/ticatec/app-data-service
- Issues: https://github.com/ticatec/app-data-service/issues
Copyright © 2023 Ticatec. All rights reserved.
