Issue:
feat(api_client): add api client trait

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [x] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
Currently we use a shared client via once cell to prevent the CPU overhead associated with creating a new `reqwest::Client`
Instead I'd propose to use a trait that can be used for defining this behavior associated with making API calls while re-using the reqwest::Client

There are 2 distinct components for this design
1. ApiClient (to be shared throughout the app & holds the underlying tcp sockets/connections etc)
2. RequestBuilder (Generated each time an request is to be made holds info specific to that request)

Both of the above components are represented as a trait ^

```rs
pub trait RequestBuilder: Send + Sync {
    /// I'm constrained to not using generics anywhere in this trait as to make it still possible to build a vtable for dyn dispatch
    /// fn json<T: Serialize>(&mut self, body: T); won't work since I won't be able to build a dyn dispatch trait out of this

    /// fn json<T: Serialize>(&mut self, body: &T); Although using reference of the generic might work
    /// ^^^will get to this once I verify that we don't need ownership of this struct
    fn json(&mut self, body: serde_json::Value);
    fn url_encoded_form(&mut self, body: serde_json::Value);
    fn timeout(&mut self, timeout: Duration);
    fn multipart(&mut self, form: Form);
    fn header(&mut self, key: String, value: Maskable<String>) -> CustomResult<(), ApiClientError>;
    /// Have avoided the usage of async_trait crate here for personal preference
    fn send(
        self,
    ) -> CustomResult<Box<(dyn core::future::Future<Output = Result<reqwest::Response, reqwest::Error>> + 'static)>, ApiClientError>;
}

pub trait ApiClient
where
    Self: Sized + Send + Sync,
{
    fn new(
        proxy_config: Proxy,
        whitelisted_urls: Vec<String>,
    ) -> CustomResult<Self, ApiClientError>;
    /// Returning a Box<dyn> here to avoid any limitations introduced by generics (mostly ergonomics)
    /// can be re-considered once the integration is done
    fn request<U: IntoUrl>(&self, method: Method, url: U) -> Box<dyn RequestBuilder>;
}
```

This can be used to implement a mock `ApiClient` as well to test connectors.


### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless its an obvious bug or documentation fix
that will have little conversation).
-->
There are a couple of existing limitations that can be solved via this:
1. limited control over initialization of the client since the initialization info needs to be passed at all points of usage
2. reduced ergonomics & abstraction since the proxy config, whitelisted URL's, certificate info needs to be passed everywhere
3. Limitations in terms of the logging & metrics we can offer since we don't have a control/abstraction over how requests are built
4. Currently unit tests can't be run on more than 1 thread due to lazy static initialization failure on multiple threads simultaneously, now we can have a separate reqwest::Client for each thread (Or also build a mock for it)

## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->

- This only covers the initial spec for defining the trait, matching the spec for existing ApiClient & requesting comments on the overall trait definitions & functionality
- Integration for this would be taken up separately

## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [ ] I addressed lints thrown by `cargo clippy`
- [x] I reviewed submitted code
- [ ] I added unit tests for my changes where possible
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable


Resolution:
<think>
PR Context:
- Title: feat(api): use `ApiClient` trait in AppState
- Merged: 2023-09-01T10:14:02Z
- Files changed: 15 files
- Commits: 3 commits

Implementation approach:
## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [x] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description

This is a micro PR for introducing `ApiClient` trait in `AppState`. This PR only adds the client but doesn't use it as of now.

It builds over: #1919 

<!-- Describe your changes in detail -->


### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR 
</think>

To implement this, you'll need to modify:


**Detailed Implementation:**


**Commit 1:** feat(api): use `ApiClient` trait in AppState (#2067)
Files to modify:


**crates/router/src/bin/scheduler.rs**
  Modify existing code

**crates/router/src/core/errors.rs**
  Modify existing code

**crates/router/src/lib.rs**
  Modify existing code

**crates/router/src/routes/app.rs**
  Modify existing code

**crates/router/src/services/api.rs**
  Modify existing code

**crates/router/src/services/api/client.rs**
  Remove:
    - function: private::request
  Add:
    - function: pub::new
    - function: private::request
    - function: private::request_with_certificate
    - impl: impl ApiClient for MockApiClient

**crates/router/src/types/storage/payment_attempt.rs**
  Modify existing code

**crates/router/tests/cache.rs**
  Modify existing code

**crates/router/tests/connectors/aci.rs**
  Modify existing code

**crates/router/tests/connectors/utils.rs**
  Modify existing code

**crates/router/tests/payments.rs**
  Modify existing code

**crates/router/tests/payments2.rs**
  Modify existing code

**crates/router/tests/services.rs**
  Modify existing code

**crates/router/tests/utils.rs**
  Modify existing code