Skip to content

Refactor Duplicate API Method Operations #150

@kenny-io

Description

@kenny-io

Most API methods in the codebase follow the same pattern: create a ticket, count events, emit start event, perform operation, emit end event, and respond. For example:

eth_getBalance: async function (args: RequestParamsLike, callback: JSONRPCCallbackTypePlain) {
    const api_name = 'eth_getBalance'
    nestedCountersInstance.countEvent('endpoint', api_name)
    if (!ensureArrayArgs(args, callback)) {
      countFailedResponse(api_name, 'Invalid params: non-array args')
      return
    }
    const ticket = crypto
      .createHash('sha1')
      .update(api_name + Math.random() + Date.now())
      .digest('hex')
    logEventEmitter.emit('fn_start', ticket, api_name, performance.now())
    /* prettier-ignore */ if (firstLineLogs) { console.log('Running eth_getBalance', args) }

    let address
    let blockNumber
    try { ... } catch (e) { ... }
    ...
     

This pattern is duplicated across all methods, making the code more verbose and harder to maintain.

Tasks:

  • Create a wrapper function that handles common API method operations
  • Apply the wrapper to one API method as a proof of concept
  • Document the pattern for other contributors to follow

Example implementation:

function wrapApiMethod(
  methodName: string,
  handler: (args: any[], callback: JSONRPCCallbackTypePlain) => Promise<void>,
  validator?: (args: any[], callback: JSONRPCCallbackTypePlain) => boolean
) {
  return async function(args: RequestParamsLike, callback: JSONRPCCallbackTypePlain) {
    // Common setup (ticket creation, event counting, etc.)
    const ticket = createTicket(methodName);
    nestedCountersInstance.countEvent('endpoint', methodName);
    logEventEmitter.emit('fn_start', ticket, methodName, performance.now());
    
    // Validate args if validator provided
    if (validator && !validator(args, callback)) {
      return;
    }
    
    try {
      // Call the actual handler
      await handler(args, callback);
      // Success handling
    } catch (error) {
      // Error handling
    } finally {
      // Common cleanup
      logEventEmitter.emit('fn_end', ticket, { success: true }, performance.now());
    }
  };
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions