@@ -9,12 +9,121 @@ summary:
99---
1010
1111Your API implementation often needs to interact with REST APIs, SOAP Web
12- Services or other forms of APIs.
12+ Services, gRPC microservices, or other forms of APIs.
1313
14- How to:
14+ To facilitate calling other APIs or web services, we introduce ` @loopback/service-proxy `
15+ module to provide a common set of interfaces for interacting with backend services.
1516
16- - Set up a Service
17- - Use services with controllers
18- - Reuse models between services and controllers
17+ ## Installation
1918
20- {% include content/tbd.html %}
19+ ```
20+ $ npm install --save @loopback/service-proxy
21+ ```
22+
23+ ## Usage
24+
25+ ### Define a data source for the service backend
26+
27+ ``` ts
28+ import {DataSourceConstructor , juggler } from ' @loopback/service-proxy' ;
29+
30+ const ds: juggler .DataSource = new DataSourceConstructor ({
31+ name: ' GoogleMapGeoCode' ,
32+ connector: ' rest' ,
33+ options: {
34+ headers: {
35+ ' accept' : ' application/json' ,
36+ ' content-type' : ' application/json'
37+ }
38+ },
39+ operations: [
40+ {
41+ template: {
42+ method: ' GET' ,
43+ url: ' http://maps.googleapis.com/maps/api/geocode/{format=json}' ,
44+ query: {
45+ address: ' {street},{city},{zipcode}' ,
46+ sensor: ' {sensor=false}'
47+ },
48+ responsePath: ' $.results[0].geometry.location[0]'
49+ },
50+ functions: {
51+ geocode: [' street' , ' city' , ' zipcode' ]
52+ }
53+ }
54+ ]
55+ });
56+ ```
57+
58+ ### Bind data sources to the context
59+
60+ ``` ts
61+ import {Context } from ' @loopback/context' ;
62+
63+ const context = new Context ();
64+ context .bind (' dataSources.geoService' ).to (ds );
65+ ```
66+
67+ ** NOTE** : Once we start to support declarative datasources with ` @loopback/boot ` ,
68+ the datasource configuration files can be dropped into ` src/datasources ` to be
69+ discovered and bound automatically.
70+
71+ ### Declare the service interface
72+
73+ To promote type safety, we recommend you to declare data types and service
74+ interfaces in TypeScript and use them to access the service proxy.
75+
76+ ``` ts
77+ interface GeoCode {
78+ lat: number ;
79+ lng: number ;
80+ }
81+
82+ interface GeoService {
83+ geocode(street : string , city : string , zipcode : string ): Promise <GeoCode >;
84+ }
85+ ```
86+
87+ Alternately, we also provide a weakly-typed generic service interface as follows:
88+
89+ ``` ts
90+ /**
91+ * A generic service interface with any number of methods that return a promise
92+ */
93+ export interface GenericService {
94+ [methodName : string ]: (... args : any []) => Promise <any >;
95+ }
96+ ```
97+
98+ To reference the ` GenericService ` :
99+
100+ ``` ts
101+ import {GenericService } from ' @loopback/service-proxy' ;
102+ ```
103+
104+ ** NOTE** : We'll introduce tools in the future to generate TypeScript service
105+ interfaces from service specifications such as OpenAPI spec.
106+
107+ ### Declare service proxies for your controller
108+
109+ If your controller needs to interact with backend services, declare such
110+ dependencies using ` @serviceProxy ` on constructor parameters or instance
111+ properties of the controller class.
112+
113+ ``` ts
114+ import {serviceProxy } from ' @loopback/service-proxy' ;
115+
116+ export class MyController {
117+
118+ @serviceProxy (' geoService' )
119+ private geoService: GeoService ;
120+
121+ }
122+ ```
123+
124+ ### Get an instance of your controller
125+
126+ ``` ts
127+ context .bind (' controllers.MyController' ).toClass (MyController );
128+ const myController = await context .get <MyController >(' controllers.MyController' );
129+ ```
0 commit comments