Stampit.js入门开发者求助:视图与Rest API服务实现及日志优化
你的Stamp + REST API实现方向分析与日志优化建议
首先,先给你的实现方向点个赞!你完全踩中了Stamp编程的核心思想——组合式关注点分离:
- 把
HasHttpClient、HasApiVersion、HasUrl这些通用能力拆成独立Stamp, - 再通过
compose组合出UseRestApi基础REST能力, - 接着扩展
WithGetOperation这类HTTP方法封装, - 最后落地到
CustomerRestApi业务专属API。
这种分层复用的思路非常符合Stamp的设计哲学,后续要加POST/PUT操作、其他业务API(比如OrderRestApi)都会非常方便,方向完全正确。
接下来解决你提到的日志相关问题:
1. 简化日志器注入:创建可复用的HasLogger Stamp
你现在每个Stamp都手动调用createLogger确实繁琐,我们可以把日志能力封装成一个独立的Stamp,让其他Stamp直接组合复用,自动注入带前缀的日志器:
import {compose} from '@stamp/it'; import ArgOverProp from '@stamp/arg-over-prop'; // 封装通用日志能力的Stamp const HasLogger = ArgOverProp.argOverProp('loggerName').init([ function () { // 统一创建带前缀的多级别日志方法 const prefix = `[${this.loggerName}]`; this.log = (...args) => console.log(prefix, ...args); this.warn = (...args) => console.warn(prefix, ...args); this.error = (...args) => console.error(prefix, ...args); } ]);
2. 在业务Stamp中复用HasLogger
现在只需要在需要日志的Stamp里组合HasLogger,并传入对应的loggerName即可,不用再重复写createLogger:
优化后的UseRestApi
const UseRestApi = compose(HasHttpClient, HasApiVersion, HasUrl, HasLogger).init([ function () { this.getUrl = template(this.url); } ]).methods({ query: function query(method, {params, headers, body}) { const {apiVersion} = this; const q = { baseURL: this.getUrl({apiVersion}), method, ...params != null && {params}, ...headers != null && {headers}, ...body != null && {body} }; this.log('request config:', q); // 直接用注入的log方法 return q; } });
优化后的WithGetOperation
const WithGetOperation = compose(UseRestApi, HasLogger).methods({ 'get': function get ({params}) { const q = this.query('get', {headers: {'Accept': 'application/json'}, params}); this.log('getting data'); // 直接用注入的log方法 return this.httpClient(q); } });
优化后的CustomerRestApi
const CustomerRestApi = compose(WithGetOperation, HasLogger).methods({ all: function all() { this.log('get all customers'); // 直接用注入的log方法 return this.get({params: {page: 1, limit: 15}}); } }); // 创建实例时传入对应的loggerName const customerProvider = CustomerRestApi({ url: 'http://sample.com/<%=apiVersion%>/customers', apiVersion: 'v1', httpClient: function(config) { return Promise.resolve({ status: 200, config }); }, loggerName: 'CustomerRestApi' // 传入日志前缀名称 });
3. 额外优化建议
- 如果需要全局统一日志格式(比如加上时间戳),可以直接在
HasLogger的init里修改日志方法的实现,所有组合了HasLogger的Stamp都会自动生效,不需要逐个修改。 - 可以把
HasLogger的日志方法做成可配置的(比如允许传入自定义日志函数),进一步提升灵活性:
这样如果后续要替换成第三方日志库(比如winston),只需要传入const HasLogger = compose( ArgOverProp.argOverProp('loggerName'), ArgOverProp.argOverProp('loggerImpl', {default: console}) ).init([ function () { const prefix = `[${this.loggerName}]`; this.log = (...args) => this.loggerImpl.log(prefix, ...args); this.warn = (...args) => this.loggerImpl.warn(prefix, ...args); this.error = (...args) => this.loggerImpl.error(prefix, ...args); } ]);loggerImpl参数即可。
内容的提问来源于stack exchange,提问作者Sté
相关产品推荐
相关产品推荐

