I am trying to use nestjs/swagger to create a swagger file from my back-end and I am facing a problem related to the base path. What I want to achieve is to show version as base path instead of showing it in all the methods available, which is ugly and confusing.
My API, right now, has the following structure (this is a set of what is present in app.module.ts):
const routes: Routes = [
{
path: '/api',
module: ApiModule,
children: [
{
path: '/v1',
module: V1Module,
children: [
{
path: '/orders',
module: OrdersModule
},
{
path: '/users',
module: UsersModule
}
]
}
]
}
];
This way, once I generate and check the swagger, I see all my methods following the /api/v1 prefix. This could be an example:
orders
GET /api/v1/orders
POST /api/v1/orders
GET /api/v1/orders/{order_id}
...
users
GET /api/v1/users
POST /api/v1/users
GET /api/v1/users/{user_id}
...
What I want is to get rid of /api/v1 appearing in any method. I know that SWAGGER has fields for host and basePath, but do not find any way to populate it in Nest.js. Researching, I have found that there were .setBasePath() and .addServer() methods, but they do not work for me (I am pretty sure they are deprecated).
Thank very much for your help.
If you want nestjs to add api/v1 to every endpoint then use setGlobalPrefix('api/v1') to do that.
https://docs.nestjs.com/faq/global-prefix#global-prefix
Related
In ASP.NET MVC, I used occasional calls such as Url.Content("~/Some folder/") to get the full path of different URLs.
Is there anything similar in Giraffe?
The following code comes from the default app I created with the template:
let layout (content: XmlNode list) =
html [] [
head [] [
title [] [ encodedText "TestAccountsManager" ]
link [ _rel "stylesheet"
_type "text/css"
_href "/main.css" ]
]
body [] content
]
Is /main.css relative to the root of the application? Or is it relative to the server name? In ASP.NET MVC, I would use something like ~/css/main.css, let's say. If the app is deployed under http://example/someapp/ or http://example/ I know this would work in both cases.
In the case of the default Giraffe template, where static resources get put in the WebRoot folder, it seems to work if you use:
_href "./main.css"
This allows for deploying the web application at the root of the host, or as a "folder" one level below the root.
If you are putting the static resources in a folder below the WebRoot, then resources would go in the folder:
WebRoot\Subfolder
(e.g. WebRoot\css), and the href attribute would need to be changed to:
_href "./Subfolder/main.css
(e.g. _href "./css/main.css")
I have incorporated swagger-ui in my application.
When I try and see the swagger-ui I get the documentation of the API nicely but after some time it shows some error icon at the button.
The Error message is like below:
[{"level":"error","message":"Can't read from file
http://MYIP/swagger/docs/v1"}]
I am not sure what is causing it. If I refresh it works and shows error after few seconds.
I am guessing "http://MYIP/swagger/docs/v1" is not publicly accessible.
By default swagger ui uses an online validator: online.swagger.io. If it cannot access your swagger url then you will see that error message.
Possible solutions:
Disable validation:
config.EnableSwagger().EnableSwaggerUi(c => c.DisableValidator());
Make your site publicly accessible
Host the validator locally:
You can get the validator from: https://github.com/swagger-api/validator-badge#running-locally
You will also need to tell swaggerui the location of the validator
config.EnableSwagger().EnableSwaggerUi(c => c.SetValidatorUrl(<validator_url>));
To supplement the accepted answer...I just uncommented one line in the SwaggerConfig.cs. I only wanted to get rid of the red error on the main swagger page by disabling the validator.
// By default, swagger-ui will validate specs against swagger.io's online validator and display the result
// in a badge at the bottom of the page. Use these options to set a different validator URL or to disable the
// feature entirely.
//c.SetValidatorUrl("http://localhost/validator");
c.DisableValidator();
If you are using files from swagger-ui github repo, then you can disable schema validation from your index.html file by setting validatorUrl to null in it:
window.onload = function() {
// Build a system
const ui = SwaggerUIBundle({
url: "/docs/open_api.json",
dom_id: '#swagger-ui',
validatorUrl : null, # <----- Add this line
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
If you using PHP Laravel framework with L5-Swagger just uncomment
'validatorUrl' => null,
from the config file /config/l5-swagger.php
Setting this.model.validatorUrl = null; in dist/swagger-ui.js worked for me ..
// Default validator
if(window.location.protocol === 'https:') {
//this.model.validatorUrl = 'https://online.swagger.io/validator';
this.model.validatorUrl = null;
} else {
//this.model.validatorUrl = 'http://online.swagger.io/validator';
this.model.validatorUrl = null;
}
To anynoe having similar issue when using Swashbuckle.OData:
I was having issues to integrated Swagger with our OData endpoints (using ODataController for API and Swashbuckle.OData NuGet package). I had to write our own document filter for it and add it:
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "OurSolution.API");
c.DocumentFilter<SwaggerDocumentFilter>();
//c.CustomProvider((defaultProvider) => new ODataSwaggerProvider(defaultProvider, c, GlobalConfiguration.Configuration));
c.IncludeXmlComments(GetXmlCommentsPath());
c.UseFullTypeNameInSchemaIds();
c.RootUrl(req => ConfigurationManager.AppSettings["AppUrl"]);
})
.EnableSwaggerUi(c =>
{
c.DisableValidator();
});
Apparently in order to avoid validation error I had to comment out line which is setting ODataSwaggerProvider along with turning off validator as mentioned in posts above. This makes usefulness of Swashbuckle.OData questionable yet I didn't test whatever it works with vanilla Swashbuckle.
Note: I used approach described on GitHub page for Swashbuckle.OData but it was not working: showing no possible endpoints at all. Maybe somebody knows better solution.
using nodejs and swagger-tools v0.8.7 to route endpoints.
"basePath": "/api/myapi" in the api/myapi.json works great, ie: GET, POST, etc... at http://localhost:3000/api/myapi works.
But I still have to access http://localhost:3000/docs/ to get at the UI tool. How can I serve this from http://localhost:3000/api/myapi/docs/ ?
Same question for serving the yaml at /api/myapy/api-docs instead of /api-docs.
Thx.
got what i wanted via:
app.use(middleware.swaggerRouter(
{
swaggerUi: '/myapi.json',
controllers: './lib'
}));
app.use(middleware.swaggerUi(
{
"apiDocs": "/myapi/api",
"swaggerUi": "/myapi.json"
}
));
I was looking at AngularJs Resource documentation and it states that default actions
for accessing API are:
{'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'} };
This is a bit different from Rails RESTful API where we have index,show,new,create,edit,update and discard. Is there an "automatic" way
to bind these two without writing the path manually? Thanks!
ps. why remove and delete, where's put for update?
ngResource simply uses different names for usual REST conventions. So for example:
var User = $resource('/user/:userId', {userId:'#id'});
var user = User.get({userId:123}, function() {
// do something with user
});
In this example User.get()sends the following request GET /user/123 which Rails routing logic passes to UserController#show action.
Regarding the update method, you can simply create one yourself:
var User = $resource('/user/:id', {}, {
update: {
method: 'PUT'
}
}
My first post here, hopefully It will be right! =)
I am creating a site to manage web application development using symfony 1.4 and doctrine.
My records consist for this problem of Project and ProjectFeatures
Now what I want to do is use the admin generator to let users manage the features for one project thru a link constraining all the returned features by project_id, that would look like: http://mysite/member/project/:project_id/features
in my routing.yml configuration, I have:
member_project_feature:
class: sfDoctrineRouteCollection
options:
model: ProjectFeature
module: memberProjectFeature
prefix_path: /member/project/:project_id/features
with_show: true
column: id
with_wildcard_routes: true
project_id is an existing column in the model ProjectFeature,
I will use a custom query to retrieve features only by that project_id.
Now I can generate a url to link to that admin generator module without error using:
url_for('member_project_feature', array('project_id' => $project['id']))
And the routing system does recognise the url:
May 04 14:30:59 symfony [info] {sfPatternRouting} Match route "member_project_feature" (/member/project/:project_id/features.:sf_format) for /member/project/1/features with parameters array ( 'module' => 'memberProjectFeature', 'action' => 'index', 'sf_format' => 'html', 'project_id' => '1',)
But the admin generator can't generate it's links inside it's templates with that prefix_path and returns error InvalidArgumentException with message The "/member/project/:project_id/features/:action/action.:sf_format" route has some missing mandatory parameters (:project_id).
Any idea?
Well I found my answer at this url: http://www.blogs.uni-osnabrueck.de/rotapken/?s=symfony
But I will give it here and shorten it because, stackoverflow is awesome and it should be there for a long time =)
1st - The routing configuration I used in my question is valid.
2nd - You need to add a method in the action file generated by the admin
public function execute($sfRequest)
{
// taken from http://www.blogs.uni-osnabrueck.de/rotapken/?s=symfony
$this->forward404Unless(
$project_id = $sfRequest->getUrlParameter('project_id'));
$this->forward404Unless(
$this->project = Doctrine::getTable('ttcWebProject')->find($project_id));
$this->getContext()->getRouting()
->setDefaultParameter('project_id', $project_id);
if ($id = $sfRequest->getUrlParameter('id'))
{
$this->getContext()->getRouting()->setDefaultParameter('id', $id);
}
$result = parent::execute($sfRequest);
return $result;
}
At this point the url gets generated correctly but here is the last step to get to the end result you most probably want to achieve:
3rd - To get the list by project_id I can either provide a table method in the generator.yml, a default value to the getFilterDefaults or this method in the action file:
protected function buildQuery ()
{
$q = parent::buildQuery();
$rootAlias = $q->getRootAlias();
$q->andWhere("{$rootAlias}.project_id = ?",
$this->getRequest()->getUrlParameter('project_id'));
return $q;
}
I'm not 100% certain about what you're trying to do here, but it sounds like you need the ProjectFeature::toParams method return the project_id.