зеркало из https://github.com/Azure/ms-rest-js.git
6.6 KiB
6.6 KiB
Architecture Overview
This repository is designed to be used as a runtime companion to code that is generated using the Autorest TypeScript Generator, but this code can also be used as a standalone library too. The following is an explanation of the structure of this repository and how it's code fits together.
ServiceClient
The top-most type in this runtime repository is the ServiceClient class. This class contains some properties that may benefit from a little explanation.
- HttpClient - The HttpClient interface is a really simple type that just requires an implementing type to have one method:
sendRequest(WebResource): Promise<HttpOperationResponse>
. This method takes an HTTP request object (WebResource) and returns a Promise that resolves to an HTTP response (HttpOperationResponse). We provide default HttpClients based on your operating environment (Fetch-based for Node.js and XHR-based for browser), but you are free to implement your own HttpClient type and to provide it in the ServiceClientOptions parameter to the ServiceClient's constructor. This is particularly useful if you are migrating to use ms-rest-js from an application that already had special HTTP logic, or if you need to test a part of your application that makes HTTP requests and you want to provide a Mock HttpClient (like we do here). - RequestPolicyCreators - This array contains functions that create RequestPolicy types. In the simplest scenario, you can use a ServiceClient to send an HTTP request and that request will be provided to the ServiceClient object and it will pass that request directly to your HttpClient implementation. RequestPolicies are a way of allowing you to transform every request you send through your ServiceClient before it reaches your HttpClient. Other frameworks and libraries call these objects Interceptors or Filters. A RequestPolicy can be simplified down to the following illustration:
------- (1) ----------------- (2) ------- (3) ------- (4) -------------- (5) ~~~~~~~ | | --> | | --> | | --> | | --> | | --> ~ ~ | App | | ServiceClient | | RP1 | | RPn | | HttpClient | ~ Network ~ | | <-- | | <-- | | <-- | | <-- | | <-- ~ ~ ------- (8) ----------------- ------- (7) ------- (6) -------------- ~~~~~~~
In this illustration, we're looking at an application that uses a ServiceClient.
- First the application creates and gives an HTTP request (WebResource) object to the ServiceClient's sendRequest() method. When this method is called, the ServiceClient creates the pipeline that is used to transform the request. This pipeline is a singly-linked list of RequestPolicies that ends with the ServiceClient's HttpClient.
- Once the pipeline is created, the ServiceClient calls the first RequestPolicy's sendRequest() method with the HTTP request object provided to the ServiceClient's sendRequest() method. In the first RequestPolicy's sendRequest() method, the RequestPolicy either does something to the HTTP request (such as adding a User-Agent header) or does something because of the HTTP request (such as emitting logs).
- Each RequestPolicy has a nextPolicy property that points at the next RequestPolicy in the pipeline. When the current RequestPolicy is finished reacting to the HTTP request, it will call sendRequest() on the next policy in the pipeline.
- This continues until the next RequestPolicy in the pipeline is actually the HttpClient (you may have noticed that the HttpClient actually extends the RequestPolicy interface, so it can be added as the last entry in the pipeline).
- The HttpClient implementation now does whatever it needs to do to send the HTTP request across the network. Most likely the code that sends HTTP requests doesn't know how to handle a WebResource, so the HttpClient first needs to convert the WebResource HTTP request into the type that the real HTTP implementation knows how to deal with. Then it sends that converted request across the network.
- Somehow the HttpClient will get an asynchronous response from the Network (either via callback or Promise). Either way, that response needs to be converted to a Promise and returned to the previous RequestPolicy in the pipeline.
- The RequestPolicies are free to either return the response as they receive it, or they can perform additional logic based on the response (such as retrying a failed request or deserializing the response's headers and/or body).
- When the HTTP response has finally been returned from the first RequestPolicy in the pipeline, the ServiceClient returns it to your application's code, where you can handle the response however you want.