Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support file:// urls #1044

Closed
matthewadams opened this issue May 5, 2017 · 16 comments
Closed

Support file:// urls #1044

matthewadams opened this issue May 5, 2017 · 16 comments

Comments

@matthewadams
Copy link

Enhance swagger-client to support file:// urls in order to allow the use of the package from Node.js server-side code.

The following code throws an error:

const Swagger = require('swagger-client')

Swagger(`file:///${__dirname}/swagger/spec/swagger.json`).then(client => {
  if (client.errors.length) {
    console.log('@@@@@@@@@@@@@@@@')
    console.log(client.errors)
    return
  }
  // ...use client...
}).catch(err => {
  console.log('!!!!!!!!!!!!!!!!!!!')
  console.log(err)
})
!!!!!!!!!!!!!!!!!!!
Error: only absolute urls are supported
    at /Users/matthew/dev/theservice-rest/node_modules/node-fetch/index.js:54:10
    at new Fetch (/Users/matthew/dev/theservice-rest/node_modules/node-fetch/index.js:49:9)
    at Fetch (/Users/matthew/dev/theservice-rest/node_modules/node-fetch/index.js:37:10)
    at module.exports (/Users/matthew/dev/theservice-rest/node_modules/isomorphic-fetch/fetch-npm-node.js:8:19)
    at a (/Users/matthew/dev/theservice-rest/node_modules/swagger-client/dist/index.js:1:3599)
    at /Users/matthew/dev/theservice-rest/node_modules/swagger-client/dist/index.js:1:17812
    at Function.i [as resolve] (/Users/matthew/dev/theservice-rest/node_modules/swagger-client/dist/index.js:1:18339)
    at Object.resolve (/Users/matthew/dev/theservice-rest/node_modules/swagger-client/dist/index.js:1:11515)
    at Object.a (/Users/matthew/dev/theservice-rest/node_modules/swagger-client/dist/index.js:1:10734)
    at a (/Users/matthew/dev/theservice-rest/node_modules/swagger-client/dist/index.js:1:10692)

I do see https://github.com/bitinn/node-fetch/blob/master/LIMITS.md, which appears to be the underlying problem. This issue, then, is dependent on the removal of that limitation. I've commented on node-fetch/node-fetch#75 in hopes that this will be resolved.

@matthewadams
Copy link
Author

matthewadams commented May 9, 2017

@webron, Is there a workaround for being able to use swagger-js with a service that requires separate, manual download of its spec?

I was looking into it, and from a naive understanding of the code & dependencies, I'd have to fork & enhance node-fetch to support file:// urls, then fork & enhance isomorphic-fetch to use the forked node-fetch, then fork swagger-js to use the enhanced isomorphic-fetch. I could try some proxyquire trickery, but it all seems like a lot of work for little gain if there's another way to work around this.

@shockey
Copy link
Contributor

shockey commented Jun 9, 2017

@matthewadams, by this:

Is there a workaround for being able to use swagger-js with a service that requires separate, manual download of its spec

do you mean that you already have your spec downloaded, and want to provide it directly to the library?

@matthewadams
Copy link
Author

matthewadams commented Jun 10, 2017 via email

@boblauer
Copy link

A simpler alternative might be to allow a resolved spec to be passed into the client. For example:

const spec = require('./swagger-spec.json');
Swagger(spec).then(client => ...);

It seems silly to try to make a request of any sort to read a local file.

@matthewadams
Copy link
Author

@boblauer I agree

@tcosentino
Copy link

tcosentino commented Jun 27, 2017

@boblauer @matthewadams you can do this (found here)

import Swagger from 'swagger-client';
import SpecFile from '../spec.json';
Swagger({ spec: SpecFile }).then((client) => {
  console.log(client);
});

@matthewadams
Copy link
Author

matthewadams commented Jun 28, 2017 via email

@c4milo
Copy link
Contributor

c4milo commented Jun 28, 2017

@tcosentino I'm curious, why the need for the thenable call when providing the JSON spec already loaded?

@tcosentino
Copy link

@c4milo Just the way they've set up the constructor. I assume with the spec option it isn't doing anything async, but the pattern remains the same. There may be a way to do it without, i.e. the constructor may return the client? Just haven't tried that

@shockey
Copy link
Contributor

shockey commented Jul 15, 2017

@matthewadams, did @tcosentino's solution solve your use case?

@c4milo
Copy link
Contributor

c4milo commented Jul 15, 2017

for new people landing here, this is how I did it with a Nuxt plugin:

import Vue from 'vue';
import Swagger from 'swagger-client';
import APISpec from '~assets/identity.swagger.json';

const APIClient = {
	install (Vue, options) {
		Swagger({ spec: APISpec }).then((client) => {
			Vue.prototype.$client = client;
			Vue.prototype.$api = client.apis;
		}, (error) => {
			console.error('failed to load api spec: %o', error);
		});
	}
};

Vue.use(APIClient);

@shockey
Copy link
Contributor

shockey commented Mar 1, 2018

I'm going to close this one out, here's why:

file:// URLs are not really useful, since they're very difficult to use in browsers due to Same-Origin Policy and very few Node request libraries support them.

As for loading in a definition that you already have in memory, @c4milo is correct: you can pass your definition as a JS object under the spec key.

Feel free to reply if you disagree with any of this, and I'll consider reopening. Thanks everyone!

@shockey shockey closed this as completed Mar 1, 2018
@matthewadams
Copy link
Author

@tcosentino: Just getting back to this. Your comment (#1044 (comment)) worked out nicely, and motivated me to add #1292. Thanks!

@bcomnes
Copy link

bcomnes commented Jun 21, 2018

Its unfortunate the io for fetching the spec has been so tightly coupled to the constructor of the resulting client. Seems like that complicates the default path (how is this fetch going to work?), and gets in the way (purposeless async) if you have the spec already.

@shockey
Copy link
Contributor

shockey commented Jun 22, 2018

@bcomnes, it's not completely purposeless, IMO.

We see definitions that are multiple megabytes of JSON - certainly, having the building of a client instance for that definition on the event loop is nicer than it locking up your main thread for a while.

@bcomnes
Copy link

bcomnes commented Jun 22, 2018

I was under the impression that the async step came from the fetching of a remote spec resource. The processing of the spec is also chunked across even loop turns? (e.g. using the Swagger({ spec: SpecText }).then() initialization is spread across multiple ticks?).

The use case I'm looking for here is creating a js client for an open API endpoint, similar to what the Java based code generator creates, but avoiding having to muck around with a java dependency. Perhaps there is a more direct path to that? Basically looking to create something simple that can be required/Imported without having to force async initialization by default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants