farrow-js / farrow

A Type-Friendly Web Framework for Node.js
https://www.farrowjs.com
MIT License
770 stars 37 forks source link

Feature Request(farrow-client-api): custom fetcher #142

Closed tqma113 closed 2 years ago

tqma113 commented 2 years ago

96 #98

At #98, We can do const myApiPipeline = createApiPipeline({ fetcher }). But we ignore another case: code generation at client. In the generated code. the pipeline has been created already, So we still can not custom fetcher at this case.

For now, we can pass the batch options when calling generated function. Could we add new option to the invoke function of api pipeline? Or is there any else way to solve this problem?

Expect

// Generated Code
export const api = {
  addTodo: (input: AddTodoInput, options?: ApiInvokeOptions) =>
    apiPipeline.invoke({ type: 'Single', path: ['addTodo'], input }, options) as Promise<AddTodoOutput>,

  removeTodo: (input: RemoveTodoInput, options?: ApiInvokeOptions) =>
    apiPipeline.invoke({ type: 'Single', path: ['removeTodo'], input }, options) as Promise<RemoveTodoOutput>,
}

// expect could call with custom fetcher
api.addTodo({/** input data */}, { fetcher: customFetcher })
Lucifier129 commented 2 years ago

api.setFetcher(fetcjer) will be ok?

tqma113 commented 2 years ago

Looks yes. But not functional. :eyes:

api.setFetcher(fetcjer)

or

api.addTodo({/** input data */}, { fetcher: customFetcher })

?

Lucifier129 commented 2 years ago

We can follow the principle of functional core, imperative shell, and ask a question 'Is it fetcher at the core or at the boundary?'

pipeline.use(middleware) is already dependent on an internal mutable shared state, it let use write many middlewares in a separate way instead of chainable style.

Use functional style in JavaScript/TypeScript is given its cost. We can gain more benefits at the core of our logic to cover the cost.

So, in my opinion, fetcher is something at the boundary, it will be ok to use imperative style rather than functional style.

Of course, an elegant functional approach solve the same problem perfectly will be the best way.

Lucifier129 commented 2 years ago

And api.addTodo({/** input data */}, { fetcher: customFetcher }) is not equal to api.setFetcher(fetcher) since it only works once.

tqma113 commented 2 years ago

When people want to add a specific header to a single request(calling), seems that only api.setFetcher(fetcher) can't do this. Maybe we could support both of them?

Lucifier129 commented 2 years ago

Yes, it makes sense.

options.fetcher > setFetcer(fetcher) > default fetcher

tqma113 commented 2 years ago

https://www.npmjs.com/package/farrow-api-client/v/1.11.1