hapi-swagger / hapi-swagger Goto Github PK
View Code? Open in Web Editor NEWA Swagger interface for hapi
Home Page: https://hapi.dev/
License: MIT License
A Swagger interface for hapi
Home Page: https://hapi.dev/
License: MIT License
Now that Hapi 5 is out with some breaking changes in Joi, this plugin needs a fix for compatibility.
I see form-url-encoded payload support was removed. Shouldn't the payload type be a setting?
Is anyone working on support for responses and response class definitions etc.? If not, we'll do a fork to add that.
I love what this plugin can do, but beyond Hapi v4, it is complaining due to what appears to be some minor schema changes in the validation definitions from Hapi. In addition to that Eran Hammer announced breaking changes coming with version 6 of Hapi that directly impacts how server plugins are registered. He has posted details on how to migrate existing plugins to the upcoming 6.0 release and maintain backwards compatibility. ( hapijs/hapi#1664 ) This should probably be listed as 2 separate issues, but they are both related with maintain compatibility with newer versions of Hapi.
Hello Guys,
First of all, absolutely great work! The plugin is amazing!
I'm wondering if there is a way of "recursively" add the properties for the "payload" ?
Getting this method as an example:
Would is be possible to generate one field for each property of "data" and "session", instead of expecting one json string representation of the object?
If not, could you please consider this as a feature request?
Unfortunately i have to keep backwards compatibility in this implementation so i can't "promote" the properties to be one level up : (
Anyway i think ( and hope ) this feature would be very useful for many users.
Thank you very much
validating route path param with Joi.string().regex(/^[0-9a-fA-F]{24}$/).allow('me')
- produces select with option me
, so we cant test any other valid path params.
maybe use Joi Any.example
method in this case to populate options or just leave test input and add extra info about allowed values?
I have a POST method with a required fields and an optional field. I input text into the required field and hit the 'Try it out' button but it is failing validation stating that the required field wasn't specified.
The first time I set a payload or response schema in an array of routes it is stuck and even if I define another schema in a payload or response for the same route or one with a different method.
I was trying to have a POST body with attributes and return a response object which was the same and also included an 'id' attribute that wasn't present in the payload.
All payloads are validated properly. They are just displayed in the UI improperly.
Keep up the great work!
The swagger spec supports enums to specify pre-defined options:
"status": {
"type": "string",
"description": "Order Status",
"enum": [
"placed",
" approved",
" delivered"
]
},
I know that joi doesn't support the enum() function. Any idea how we could add this here?
Joi.string().example("hapi-swagger")
I am curious if there is possibility to achieve this: http://swagger.wordnik.com/#!/pet/uploadFile
Hello guys,
I think i found an issue in the case where the route path variable name matches its payload name. When they are the same strings, the model schema will not show the right detail.
Here is simplified example of what i mean.
exports.routes = [
{
path: '/students',
config: {
//some more code here
tags: ['my_tag'],
validate: {
payload: {
students: Joi.array().required().min(1).includes(validator.schema)
},
}
}
]
The validator.schema contains several fields required for each 'students' element in the array,
none of these fields would show up under the model schema of the hapi-swagger page when the array name (students) matches the path name (students)
hapi on npm is version 2.2.0
npm ERR! peerinvalid The package hapi does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants hapi@~2.1.1
npm ERR! System Linux 3.11.0-15-generic
npm ERR! command "/usr/bin/node" "/usr/bin/npm" "install" "hapi-swagger" "--save"
npm ERR! cwd /home/deskx/Aplicativos/node.ssh/ssh.api
npm ERR! node -v v0.10.25
npm ERR! npm -v 1.3.24
npm ERR! code EPEERINVALID
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /home/deskx/Aplicativos/node.ssh/ssh.api/npm-debug.log
npm ERR! not ok code 0
I have added the swagger for my DELETE method but instead of an input box for my id path variable it is just the text '(empty)'
@glennjones excellent work on this, the be-more-hapi.js project is a great example of it in use. Have you plans to update it to the latest Hapi version (6.x) ?
so let's say, one method has:
path : '/one_method'
config :
validate:
payload:
data: t.object().keys
something : t.string().required()
anything : t.string().default( "ios" )
and the oner one:
path : '/another_method'
config :
validate:
payload:
data: t.object().keys
name : t.string().required()
age : t.string().required()
Both will result with duplicated documentation for "payload.data".
Basically then any method which contains "data" as "child" of "payload" will result with identical documentation @ swagger UI.
When checking the json generated by "/docs", i could spot that it exports 1 "model" per "object" inside of the payload, so i believe the /docs json structure will have to change in order to honour the data.
This is a minor thing, but it would be nice to be able to configure the name on the logo
Hi Glenn
In the latest release (0.0.4) I'm getting an error thrown on line 55 of hapi-swagger/lib/index.js:
'ReferenceError: resourceName is not defined'
This is the code that throws the error:
if(resourceName){
but I don't see resourceName used or defined anywhere else other than as an input param to the new function 'isResourceRoute'. Where is that value meant to come from?
David
If I generate schema:
var schema = Joi.object({
_id: Joi.any().required(),
name: Joi.string().required()
}).options({
className: 'User'
});
that I include it let's say in response schema and then - I modify it like below:
var schema2 = schema.keys({
name: Joi.string().optional()
});
or
var schema2 = schema.optionalKeys('name')
Swagger UI shows first schema (schema1) everywhere instead of displaying schema2 in request parameters.
After removing className, everything works as expected. This might be a bug due to className resolving.
It is hard coded to application/json. The UI should be able to send any text based format as long and the API can deal with it. Hapi will allow any text/* type through untouched for a plug to deal with it.
For my use case, I generate for several clients an API, they all have their seperate path, i.e. /client-a
or /client-b
.
What I'd like to do is generate API docs for each client seperately. So that /client-a/docs
shows all available routes for Client A und /client-b/docs
everything client B need to know.
If I understand the current implementation correctly, this is not yet possible. Is that correct? My suggestion would be to add another tag to all routes that belong to one client and then be able to generate docs for all routes that e.g. have the tags api
and client-a
.
I'd be happy to dig into that and contribute this functionality. I just wanted to make sure, that this is not yet possible, before I start to implement.
I have a route like
/{version}/services/{cc_}
{cc_} is an optional parameter in Hapi, but when I leave the field parameter empty, the rest call is not executed, do you know how to make this work
thanks
I was running into a bug related to an array as the first responseObject and I'm working on a fix for it. I can't tell for sure, but it looks like the logic in this block of code may be reversed. Can you take a look at it and clarify?
if (arrayProperty['enum']) {
property.items = {
'$ref': arrayProperty.type
};
} else {
property.items = {
'type': arrayProperty.type,
'enum': arrayProperty['enum']
};
}
shouldn't it be:
if (arrayProperty['enum']) {
property.items = {
'type': arrayProperty.type,
'enum': arrayProperty['enum']
};
} else {
property.items = {
'$ref': arrayProperty.type
};
}
If so, I will include that change in a pull request I'm getting ready to submit.
There is a bug with the version of swagger-ui currently included in hapi-swagger (see swagger-api/swagger-ui#180). Apparently it was partially fixed but still broken for form params. I posted the fix at that link.
Joi.object({...}).options({className: 'CustomName'});
doesn't work with v0.4.1. Swagger UI shows Model_xxx
instead of CustomName
Hi
I have a route with query validation:
validate: {
query: {
field: joi.array().default([ 'field1', 'field2', 'field3' ])
}
}
The default value in the "try it out" section is field1, field2, field3
This is the wrong way to write an in a query parameter and it leads to bad request error.
It should have been ["field1", "field2", "field3"]
It looks like the Swagger UI has a problem with hapi-style optional path parameters. With a route defined as:
/books/{id}/cover
Swagger UI has no trouble at all. It documents the route, and enables me to invoke it from the UI. Great!
But when a parameterized path contains an optional parameter at the end, it has a problem:
/library/shelves/{shelfId}/book/{id?}
Here it documents the route, including the optional parameter segment. But when I try to execute the from the UI, leaving the optional parameter blank, the UI never invokes the API.
Did I miss something in the documentation? Or is this an issue?
All of the urls in the html file for the UI are hardcoded to /docs. if you change the endpoint setting, then all of the files 404
The plug-in needs to be refactored and based more heavily on good test coverage. The constant changes to HAPI have brought the project to a point it needs to be recoded. I going to open up a dev branch and start to work soon.
I will try and keep up with fixes and any more breaking changes from HAPI in the meantime.
Hi Glenn,
Can't thank you enough for 6.x support, was in the middle of making a PR when I saw the commit. It all works nearly perfect, but I've found one issue though, if you have a route with payload in the validation object it prevents the swagger-ui from loading with the error:
[ 'start' ] 'be-more-hapi - web interface: http://localhost:3000'
Debug: hapi, internal, implementation, error
TypeError: Uncaught error: Object.keys called on non-object
It works fine for validating params and query, just a problem with payload. Will try to debug and make a PR, but I'm sure you've a better idea of what's happening.
Thanks again for the quick response in providing 6.x support.
When I tag and endpoint with 'api' the plugin pick up all get/post/put... and sub endpoints within that module.
Fixed with
if(!route.settings.tags || route.settings.tags.indexOf('api') < 0) return;
in line 115 if you accept pull requests.
Is there anything in the pipeline to extract model schemas from hapi validation for array and object parameters?
I'd be interested in looking into this.
I noticed that there is small issue with declaration of Crypto module. It is defined like this:
var Hoek = require('hoek'),
Boom = require('boom'),
Joi = require('joi'),
Path = require('path');
Crypto = require('crypto');
Instead of ;
there should be ,
after Path declaration.
I usually run into this issue every update, so thought I'd mention it in case there may be an easy work around.
I version all my endpoints e.g. /v2/item
and so on, so every swagger resource is loaded under the prefix /v2, which works fine, as my page that loads swagger I can define the resource locations as being under /v2, e.g.
<script src='/v2/docs/swaggerui/lib/shred.bundle.js' type='text/javascript'></script>
<script src='/v2/docs/swaggerui/lib/jquery-1.8.0.min.js' type='text/javascript'></script>
<script src='/v2/docs/swaggerui/lib/jquery.slideto.min.js' type='text/javascript'></script>
<script src='/v2/docs/swaggerui/lib/jquery.wiggle.min.js' type='text/javascript'></script>
<script src='/v2/docs/swaggerui/lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
<script src='/v2/docs/swaggerui/lib/handlebars-1.0.0.js' type='text/javascript'></script>
<script src='/v2/docs/swaggerui/lib/underscore-min.js' type='text/javascript'></script>
<script src='/v2/docs/swaggerui/lib/backbone-min.js' type='text/javascript'></script>
<script src='/v2/docs/swaggerui/lib/swagger.js' type='text/javascript'></script>
However, I can't specify the throbber.gif url as it's hardcoded in the swagger-ui.js file here: https://github.com/glennjones/hapi-swagger/blob/master/public/swaggerui/swagger-ui.js#L355
I can easily go in and edit this (I know that's bad practice, but I don't know of an alternative!) to be
<img alt='Throbber' class='response_throbber' src='/v2/docs/swaggerui/images/throbber.gif' style='display:none' />
which works fine, It just mean this has be done every time I update hapi-swagger or the throbber gif doesn't load. Do you know of any work around for this or fix I could provide? I imagine it's likely an edge case so I'll accept a 'wont fix' :)
Hi Glenn,
Have you plans to support the latest Hapi version? Anything I can do to help? I don't believe there were much changes to the plugin API, just the addition of reply.continue()
was the only required update to some of my plugins.
Thanks again for providing this plugin!
As above, if presence set to forbidden
, attribute shows as either optional or required (for example, if basic schema defines all the attributes as required ones and the custom schema that produces that errors defines that one attribute is forbidden - let's call it _id).
if (param._flags && param._flags.presence) {
property.required = (param._flags.presence === 'required') ? true : false;
}
Something like this if (param._flags.presence === 'forbidden') return;
at some point in the code would do the trick (as value is forbidden - we don't want our users to see it in the schema)
If this is still being maintained, you might want to pay attention to the Joi 2.0 changes coming in hapi 1.16. The internals are all different for validation rules.
headers are not supported parameters...
E.g.
validate: {
headers: {
authorization: joi.string()
.required()
.description('authorization')
},
payload: models.member.schema
}
Not urgent - but I noticed the payload definition model acts like in the image attached, where the title is model_ e.g. model_0_1_2 and so on:
Where as the swagger project lists them like:
Is this a small bug or is it likely I've something configured incorrectly? Will look into the code tomorrow, just wanted to point it out first in case it was just my config or something like that.
@glennjones I'm wondering if you anticipate updating hapi-swagger so support the latest version of hapi
?
There are some breaking changes, mostly around joi
. I might be able to submit a PR with the changes if you don't see any breaking changes that will be big blockers.
Thanks
Joi has possibility to define alternatives. Hapi-swagger will just make following markup for that:
hello {
files (alternatives)
}
There is still an issue with form arguments where swagger.js will send undefined for any fields that are empty (ie. so you'll receive something like foo=something&bar=undefined )
I posted about this at the swagger project and I think they fixed it in a recent version (they fixed the same bug for query args, although not perfectly.) For now I've fixed my local copy in hapi-swagger. It's only a few lines of code.
swagger.js line 967:
for(var i = 0; i < formParams.length; i++){
var param = formParams[i];
var value = this.params[param.name];
if (value !== undefined) {
values[param.name] = value;
}
}
var encoded = "";
for(key in values) {
value = values[key];
if(encoded !== "")
encoded += "&";
encoded += encodeURIComponent(key) + '=' + encodeURIComponent(value);
}
Hi,
Thanks for building a really cool self-documentation tool. I have a quick question regarding a missing endpoint from the doc.
It seems like that the plugin omits the main GET for a resource. For example, say I have these routes (all which are tagged: ['api']):
var routes = [
{ path: '/movies', method: 'GET', config: handlers.movies.list },
{ path: '/movies/{id}', method: 'GET', config: handlers.movies.get },
{ path: '/movies/{id}', method: 'DELETE', config: handlers.movies.delete },
{ path: '/movies/{id}', method: 'PUT', config: handlers.movies.update },
{ path: '/movies', method: 'POST', config: handlers.movies.add }
];
The doc omits GET /movies, but it does show GET /movies/:id and all other routes with a trailing slash per the library:
//lib/index.js
routes = routes.filter(function (item) {
if (request.query.path &&
item.path.indexOf('/' + request.query.path + '/') !== 0 ) {
return false;
}
return item.settings.plugins['hapi-swagger'] !== false && item.method !== 'options';
});
Was there a particular train of thought behind this? Simply removing the + '/'
from the filter seems to fix the issue. I'd be happy to submit a pull request for this.
Peer [email protected] wants [email protected]
Please update with support for hapi version 7
Swagger is using server.routingTable()
. Should be using server.table()
by the time 2.0 is official.
If route notes is an array of strings (as Hapi allows), it gets displayed by swagger-ui as a single string with each note separated by a comma. Not sure how other people are using notes but we are using Hapi notes as an array with each string being a paragraph of text.
After hapi-swagger pulls out the "special notes" (response codes, response class), I would like to see it build all the remaining notes strings into a single string separated by
markers. Then swagger-ui will render it nicely as multiple paragraphs. Any thoughts?
I apologize in advance for the long winded explanation. ๐
I have a ApiResponse schema that is the base schema for all of my api responses.
Seeing as the property result
can contain many different schemas, I wrote a "generator". (See below)
The Problem I ran into is that since this schema always has the same name, any route with a different result
schema, would just repeat the definition of the first.
For example, with following routes result
will both have the User.schema
in swagger-ui.
response.schema: ApiResponse.schema User.schema
response.schema: ApiResponse.schema Authorization.schema
However If i swap the order that they are loaded, result
(of both routes) will now contain Authorization.schema
I further proved this by dynamically generating the class name of ApiResponse.schema
(commented out below) and the problem vanished.
However, I wish for the ApiResponse
class name to remain the same for all routes, despite the schema of result
being different. Is this possible?
class ApiResponse
(@status-code, { @error, @message, @result }:details) ->
@schema = (result-schema) ->
Joi.object {
status-code: Joi.number!
.integer!
.required!
error: Joi.string!
message: Joi.string!
result: result-schema
} .options {
class-name: \ApiResponse #+ result-schema._settings.class-name
}
I'm having this issue when using same key on different configurations as detailed below:
var Person = Joi.object({
ssn: Joi.string().required()
});
var CreatePerson = Person.keys({
password: Joi.string().required()
});
var UpdatePerson = Person.keys({
password: Joi.string()
});
...
server.route([
{
method: 'POST',
path: '/person',
config: {
handler: handler,
tags: ['api'],
validate: {
payload: {
person: CreatePerson.required()
}
}
}
},
{
method: 'PUT',
path: '/person',
config: {
handler: handler,
tags: ['api'],
validate: {
payload: {
person: UpdatePerson.required()
}
}
}
}
]);
In both endpoints, person.password
is shown as required
. Here's a Gist with a functional example:
https://gist.github.com/dmacosta/f7489aad15ce85798b86
Notice replacing both person
keys into something different like a
and b
shows correct schemas.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.