1 | Swagger Client
|
2 | ===========
|
3 |
|
4 | [![Build Status](https://travis-ci.org/swagger-api/swagger-js.svg?branch=master)](https://travis-ci.org/swagger-api/swagger-js)
|
5 |
|
6 | **Swagger Client** is a JavaScript module that allows you to fetch, resolve, and interact with Swagger/OpenAPI documents.
|
7 |
|
8 | ## New!
|
9 |
|
10 | **This is the new version of swagger-js, 3.x.** The new version supports Swagger 2.0 as well as OpenAPI 3.
|
11 |
|
12 | Want to learn more? Check out our [FAQ](https://github.com/swagger-api/swagger-js/blob/master/docs/MIGRATION_2_X.md).
|
13 |
|
14 | For the older version of swagger-js, refer to the [*2.x branch*](https://github.com/swagger-api/swagger-js/tree/2.x).
|
15 |
|
16 |
|
17 | ## Note:
|
18 | The npm package is called `swagger-client` and the GitHub repository is `swagger-js`.
|
19 | We'll be consolidating that soon. Just giving you the heads up. You may see references to both names.
|
20 |
|
21 | ### Usage
|
22 |
|
23 | ##### Prerequisites
|
24 | - Runtime:
|
25 | - browser: es5 compatible. IE11+
|
26 | - node v4.x.x
|
27 | - Building
|
28 | - node v6.x.x
|
29 |
|
30 | ##### Download via npm
|
31 |
|
32 | ```
|
33 | npm install swagger-client
|
34 | ```
|
35 |
|
36 | ##### Import in code
|
37 |
|
38 | ```javascript
|
39 | import Swagger from 'swagger-client'
|
40 | // Or commonjs
|
41 | const Swagger = require('swagger-client')
|
42 | ```
|
43 |
|
44 | ##### Import in browser
|
45 |
|
46 | ```html
|
47 | <script src='browser/swagger-client.js' type='text/javascript'></script>
|
48 | <script>
|
49 | var swaggerClient = new SwaggerClient(specUrl);
|
50 | </script>
|
51 | ```
|
52 |
|
53 |
|
54 | #### API
|
55 |
|
56 | This lib exposes these functionalities for Swagger 2.0 and OpenAPI 3:
|
57 |
|
58 | - Static functions for...
|
59 | - HTTP Client
|
60 | - Document Resolver (monolithic & subtree)
|
61 | - TryItOut Executor
|
62 | - A constructor with the methods...
|
63 | - HTTP Client, for convenience
|
64 | - Document Resolver, which will use `url` or `spec` from the instance
|
65 | - TryItOut Executor, bound to the `http` and `spec` instance properties
|
66 | - Tags Interface, also bound to the instance
|
67 |
|
68 | HTTP Client
|
69 | -----------
|
70 |
|
71 | `Swagger.http(req)` exposes a [Fetch-like interface](https://github.com/lquixada/cross-fetch) with a twist: allowing `url` in the request object so that it can be passed around and mutated. It extends Fetch to support request and response interceptors and performs response & header serialization. This method could be overridden to change how SwaggerJS performs HTTP requests.
|
72 |
|
73 | ```js
|
74 | // Fetch-like, but support `url`, `query` and `xxxInterceptor`
|
75 | const request = {
|
76 | url,
|
77 | query,
|
78 | method,
|
79 | body,
|
80 | headers,
|
81 | requestInterceptor,
|
82 | responseInterceptor,
|
83 | userFetch
|
84 | }
|
85 |
|
86 | Swagger.http(request)
|
87 | .then((res) => {
|
88 | res.statusCode // status code
|
89 | res.statusText // status text, ie: "Not Found"
|
90 | res.body // JSON object or undefined
|
91 | res.obj // same as above, legacy
|
92 | res.text // textual body, or Blob
|
93 | res.headers // header hash
|
94 | })
|
95 | .catch((err) => {
|
96 | err // instanceof Error
|
97 | err.response // response or null
|
98 | })
|
99 |
|
100 | // Interceptors
|
101 | Swagger.http({
|
102 | requestInterceptor: (req: Request) => Request | Promise<Request>
|
103 | responseInterceptor: (res: Response) => Response | Promise<Response>
|
104 | })
|
105 |
|
106 | // Custom Fetch
|
107 | Swagger.http({
|
108 | userFetch: (url: String, options: Object) => Promise
|
109 | })
|
110 |
|
111 | ```
|
112 |
|
113 | Swagger Specification Resolver
|
114 | ---------------------
|
115 |
|
116 | `Swagger.resolve({url, spec, http})` resolves `$ref`s (JSON-Refs) with the objects they point to.
|
117 |
|
118 | ```js
|
119 |
|
120 | Swagger.resolve({url, spec, http}).then((resolved) => {
|
121 | resolved.errors // resolution errors, if any
|
122 | resolved.spec // the resolved spec
|
123 | })
|
124 | ```
|
125 | > This is done automatically if you use the constructor/methods
|
126 |
|
127 | TryItOut Executor
|
128 | -----------------
|
129 | An HTTP client for OAS operations, maps an operation and values into an HTTP request.
|
130 |
|
131 | ```js
|
132 | const params = {
|
133 | spec,
|
134 |
|
135 | operationId, // Either operationId, or you can use pathName + method
|
136 | (pathName),
|
137 | (method),
|
138 |
|
139 | parameters, // _named_ parameters in an object, eg: { petId: 'abc' }
|
140 | securities, // _named_ securities, will only be added to the request, if the spec indicates it. eg: {apiKey: 'abc'}
|
141 | requestContentType,
|
142 | responseContentType,
|
143 |
|
144 | (http), // You can also override the HTTP client completely
|
145 | (userFetch), // Alternatively you can just override the fetch method (if you want to use request.js or some other HttpAgent)
|
146 | }
|
147 |
|
148 | // Creates a request object compatible with HTTP client interface.
|
149 | // If `pathName` and `method`, then those are used instead of operationId. This is useful if you're using this dynamically, as `pathName` + `method` are guarenteed to be unique.
|
150 | const res = Swagger.execute({...params})
|
151 |
|
152 | // You can also generate just the request ( without executing... )
|
153 | const req = Swagger.buildRequest({...params})
|
154 | ```
|
155 |
|
156 | Constructor and methods
|
157 | -----------------------
|
158 |
|
159 | Resolve the spec and expose some methods that use the resolved spec:
|
160 |
|
161 | - `Swagger(url, opts): Promise`
|
162 | - Exposes tags interface (see above)
|
163 | - Exposes the static functions: `execute`, `http`, `resolve` and some other minor ones
|
164 | - Exposes `#http`, `#execute` and `#resolve` bound to the instance
|
165 |
|
166 | ```javascript
|
167 | Swagger('http://petstore.swagger.io/v2/swagger.json')
|
168 | .then( client => {
|
169 | client.spec // The resolved spec
|
170 | client.originalSpec // In case you need it
|
171 | client.errors // Any resolver errors
|
172 |
|
173 | // Tags interface
|
174 | client.apis.pet.addPet({id: 1, name: "bobby"}).then(...)
|
175 |
|
176 | // TryItOut Executor, with the `spec` already provided
|
177 | client.execute({operationId: 'addPet', parameters: {id: 1, name: "bobby") }).then(...)
|
178 | })
|
179 |
|
180 | ```
|
181 |
|
182 | Tags Interface
|
183 | --------------
|
184 | A client for operations. We're currently using the `apis[tag][operationId]:ExecuteFunction` interface, which can be disabled entirely using `Swagger({disableInterfaces: true})` if you don't need it.
|
185 |
|
186 | OperationId's are meant to be unique within spec, if they're not we do the following:
|
187 | - If a tag is absent, we use `default` as the internal tag
|
188 | - If an operationId is missing, we deduce it from the http method and path, i.e. `${method}${path}`, with non-alphanumeric characters escaped to `_`. See these tests ([1](https://github.com/swagger-api/swagger-js/blob/7da5755fa18791cd114ecfc9587dcd1b5c58ede1/test/helpers.js#L7), [2](https://github.com/swagger-api/swagger-js/blob/7da5755fa18791cd114ecfc9587dcd1b5c58ede1/test/helpers.js#L77)) for examples.
|
189 | - If an operationId is duplicated across all operationIds of the spec, we rename all of them with numbers after the ID to keep them unique. You should not rely on this, as the renaming is non-deterministic. See [this test](https://github.com/swagger-api/swagger-js/blob/7da5755fa18791cd114ecfc9587dcd1b5c58ede1/test/helpers.js#L127) for an example.
|
190 |
|
191 | ```js
|
192 | Swagger({ url: "http://petstore.swagger.io/v2/swagger.json" }).then((client) => {
|
193 | client
|
194 | .apis
|
195 | .pet // tag name == `pet`
|
196 | .addPet({ // operationId == `addPet`
|
197 | id: 1,
|
198 | body: {
|
199 | name: "bobby",
|
200 | status: "available"
|
201 | }
|
202 | })
|
203 | .then(...)
|
204 | })
|
205 | ```
|
206 |
|
207 | If you'd like to use the operationId formatting logic from Swagger-Client 2.x, set the `v2OperationIdCompatibilityMode` option:
|
208 |
|
209 | ```js
|
210 | Swagger({
|
211 | url: "http://petstore.swagger.io/v2/swagger.json",
|
212 | v2OperationIdCompatibilityMode: true
|
213 | }).then((client) => {
|
214 | // do things as usual
|
215 | })
|
216 | ```
|
217 |
|
218 | #### OpenAPI 3.0
|
219 |
|
220 | OpenAPI 3.0 definitions work in a similar way with the tags interface, but you may need to provide additional data in an `options` object for server variables and request bodies, since these items are not actual parameters:
|
221 |
|
222 | ```js
|
223 | Swagger({...}).then((client) => {
|
224 | client
|
225 | .apis
|
226 | .pet // tag name == `pet`
|
227 | .addPet({ // operationId == `addPet`
|
228 | id: 1
|
229 | }, {
|
230 | requestBody: {
|
231 | name: "bobby",
|
232 | status: "available"
|
233 | },
|
234 | server: "http://petstore.swagger.io/{apiPrefix}/", // this should exactly match a URL in your `servers`
|
235 | serverVariables: {
|
236 | apiPrefix: "v2"
|
237 | }
|
238 | })
|
239 | .then(...)
|
240 | })
|
241 | ```
|
242 |
|
243 | In Browser
|
244 | ----------
|
245 |
|
246 | Prepare swagger-client.js by `npm run build-bundle`
|
247 | Note, browser version exports class `SwaggerClient` to global namespace
|
248 | If you need activate CORS requests, just enable it by `withCredentials` property at `http`
|
249 |
|
250 | ```html
|
251 | <html>
|
252 | <head>
|
253 | <script src='browser/swagger-client.js' type='text/javascript'></script>
|
254 | <script>
|
255 |
|
256 | var specUrl = 'http://petstore.swagger.io/v2/swagger.json'; // data urls are OK too 'data:application/json;base64,abc...'
|
257 | SwaggerClient.http.withCredentials = true; // this activates CORS, if necessary
|
258 |
|
259 | var swaggerClient = new SwaggerClient(specUrl)
|
260 | .then(function (swaggerClient) {
|
261 | return swaggerClient.apis.pet.addPet({id: 1, name: "bobby"}); // chaining promises
|
262 | }, function (reason) {
|
263 | console.error("failed to load the spec" + reason);
|
264 | })
|
265 | .then(function(addPetResult) {
|
266 | console.log(addPetResult.obj);
|
267 | // you may return more promises, if necessary
|
268 | }, function (reason) {
|
269 | console.error("failed on API call " + reason);
|
270 | });
|
271 | </script>
|
272 | </head>
|
273 | <body>
|
274 | check console in browser's dev. tools
|
275 | </body>
|
276 | </html>
|
277 |
|
278 | ```
|
279 |
|
280 |
|
281 | Compatibility
|
282 | -------------
|
283 |
|
284 | SwaggerJS has some legacy signature _shapes_.
|
285 |
|
286 | ### Execute
|
287 | ##### Response shape
|
288 | ```js
|
289 | // swagger-js
|
290 | {
|
291 | url,
|
292 | method,
|
293 | status,
|
294 | statusText,
|
295 | headers,
|
296 |
|
297 | data, // The textual content
|
298 | obj // The body object
|
299 | }
|
300 |
|
301 | // New shape
|
302 | {
|
303 | url,
|
304 | method,
|
305 | status,
|
306 | statusText,
|
307 | headers, // See note below regarding headers
|
308 |
|
309 | text, // The textual content
|
310 | body, // The body object
|
311 | }
|
312 | ```
|
313 |
|
314 | ##### Serializing Headers
|
315 |
|
316 | By default the instance version of `#http` serializes the body and headers.
|
317 | However, headers pose an issue when there are multiple headers with the same name.
|
318 | As such we've left the static version of `http` to not perform any serialization.
|
319 |
|
320 | ### Build
|
321 |
|
322 | ```sh
|
323 | npm install
|
324 | npm run test # run test
|
325 | npm run test:watch # run test with change watching
|
326 | npm run lint # run lint
|
327 | npm run build # package to release
|
328 | npm run build-dev # package with non-minified dist/index.js (for debugging)
|
329 | npm run build-bundle # build browser version available at .../browser
|
330 | ```
|
331 |
|
332 | # Migration from 2.x
|
333 |
|
334 | There has been a complete overhaul of the codebase.
|
335 | For notes about how to migrate coming from 2.x,
|
336 | please see [Migration from 2.x](docs/MIGRATION_2_X.md)
|
337 |
|
338 | ## Security contact
|
339 |
|
340 | Please disclose any security-related issues or vulnerabilities by emailing [security@swagger.io](mailto:security@swagger.io), instead of using the public issue tracker.
|
341 |
|
342 | ### Graveyard
|
343 |
|
344 | For features known to be missing from 3.x please see [the Graveyard](docs/GRAVEYARD.md)
|
345 |
|