You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, the top-level Swagger() function accepts a spec option, which can be used if the Open API Specification document has already been retrieved. In that case, there is no need for asynchronous behavior, as there is no I/O taking place while parsing the spec.
Due to circumstances beyond our control, we are required to download the spec separately from the location at which we invoke the service provider's endpoints, and we'd like to construct our own classes (that delegate to the Swagger client) by using the spec in the classes' constructor. Without synchronous Swagger client initialization, we are required to instead implement an asynchronous initialization pattern where a user instantiates a class synchronously (because constructors are synchronous), then calls an async init() function. This pattern looks like the following.
Note: this uses Node.js on the server side.
class AbstractSwaggerEndpoint {
constructor(spec) { // subclass provides loaded spec by calling super(spec)
this._spec = spec
this._initialized = false
}
// instance method inside class AbstractSwaggerEndpoint
async init () {
if (this._initialized) return this
// return from static cache if client has already been built
this._client = AbstractSwaggerEndpoint.CLIENTS[this.constructor.name]
if (this._client) {
this._initialized = true
return this
}
// asynchronously build then cache swagger client
this._client = AbstractSwaggerEndpoint.CLIENTS[this.constructor.name] = await Swagger({
spec: this._spec
})
this._initialized = true
return this
}
// ...
}
// static cache; key is subclass name, value is swagger client
AbstractSwaggerEndpoint.CLIENTS = {}
Then, to encapsulate users from this pattern, we offer a static factory method pattern like the following.
Subclass.new = async opts => new Subclass(opts).init()
This allows users to call await Subclass.new(opts) instead of const sub = new Subclass(opts) then await sub.init().
This is a lot of work for the scenario where the spec is already in hand. If swagger-client offered a synchronous, top-level function like Swagger.fromSpec(opts) or similar, where opts was required, at mininum, to have a spec property containing the spec as a JavaScript object, we could avoid the asynchronous initialization pattern described above.
The text was updated successfully, but these errors were encountered:
Currently, the top-level Swagger() function accepts a spec option, which can be used if the Open API Specification document has already been retrieved.
Due to some legacy reasons, instantiating SwaggerClient returns an instance locked inside a Promise, instead of an instance itself. We'll rectify this issue in next major release of SwaggerClient where we're gonna be able to do breaking changes.
In that case, there is no need for asynchronous behavior, as there is no I/O taking place while parsing the spec.
Actually there is. If you already have a spec then it can contain remote JSON References which do need to be resolved. And because of that resolution is an asynchronous operation.
This is a lot of work for the scenario where the spec is already in hand. If swagger-client offered a synchronous, top-level function like Swagger.fromSpec(opts) or similar, where opts was required, at mininum, to have a spec property containing the spec as a JavaScript object, we could avoid the asynchronous initialization pattern described above.
Actually there is a static method SwaggerClient.resolve that returns resolved specification instead of SwaggerClient instance. More about this method can be found in OpenApi Definition Resolver. But again, as I mentioned before resolution is an asynchronous operation so the method returns a Promise.
Regarding building instances of swagger-client and executing them later...maybe following code fragment will help:
constassign=require('lodash/assign');constSwaggerClient=require('swagger-client');functionSwaggerClientSync(url,opts={}){this.url=url;this.opts=opts;returnthis;}SwaggerClientSync.prototype.init=asyncfunctioninit(){constclient=awaitnewSwaggerClient(this.url,this.opts);deletethis.url;deletethis.opts;returnassign(this,client);};constclient=newSwaggerClientSync({url: 'http://petstore.swagger.io/v2/swagger.json'});client.init().then(()=>console.dir('initialized and resolved'));
Currently, the top-level
Swagger()
function accepts aspec
option, which can be used if the Open API Specification document has already been retrieved. In that case, there is no need for asynchronous behavior, as there is no I/O taking place while parsing the spec.Due to circumstances beyond our control, we are required to download the spec separately from the location at which we invoke the service provider's endpoints, and we'd like to construct our own classes (that delegate to the Swagger client) by using the spec in the classes' constructor. Without synchronous Swagger client initialization, we are required to instead implement an asynchronous initialization pattern where a user instantiates a class synchronously (because constructors are synchronous), then calls an
async init()
function. This pattern looks like the following.Then, to encapsulate users from this pattern, we offer a static factory method pattern like the following.
This allows users to call
await Subclass.new(opts)
instead ofconst sub = new Subclass(opts)
thenawait sub.init()
.This is a lot of work for the scenario where the spec is already in hand. If
swagger-client
offered a synchronous, top-level function likeSwagger.fromSpec(opts)
or similar, whereopts
was required, at mininum, to have aspec
property containing the spec as a JavaScript object, we could avoid the asynchronous initialization pattern described above.The text was updated successfully, but these errors were encountered: