How to configure Swashbuckle.AspNetCore.CLI like I can configure Swashbuckle.AspNetCore.Swagger in startup.cs - swashbuckle

I need to configure Swashbuckle CLI to generate an Swagger spec in the OpenAPI 2.0 version. I do this in startup.cs with the following code:
public void Configure(IApplicationBuilder application, IWebHostEnvironment environment)
{
application.UseSwagger(c =>
{
c.SerializeAsV2 = true;
});
application.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/edgezones.json", "EdgeZoneRP Swagger");
});
}
...
}
but startup.cs seems to have no effect on Swashbuckle CLI's Swagger generation, as swagger tofile generates a Swagger spec in the OpenAPI 3.0 version (the default)

Turns out that reading the manual page can help!
Usage: dotnet swagger tofile [options] [startupassembly] [swaggerdoc]
startupassembly:
relative path to the application's startup assembly
swaggerdoc:
name of the swagger doc you want to retrieve, as configured in your startup class
options:
--output: relative path where the Swagger will be output, defaults to stdout
--host: a specific host to include in the Swagger output
--basepath: a specific basePath to include in the Swagger output
--serializeasv2: output Swagger in the V2 format rather than V3
--yaml: exports swagger in a yaml format

Related

AWS Amplify REST API cannot find the API

I'm playing with AWS Amplify since I've to introduce some of its feature in a legacy application that has no framework (no React, no Angular: just vanilla JS).
I used successfully the Auth module so I recreated a simple sign up/in/out strategy. What I want now is to call a REST API, using REST API module. So I created an API using API Gateway PetStore example and I would interact with it.
So I created the configuration:
import Amplify from '#aws-amplify/core';
Amplify.configure({
Auth: {
...
},
API: {
endpoints: [
{
name: "PetStore", // name of the API in API Gateway console
endpoint: "https://XXX.execute-api.eu-central-1.amazonaws.com/dev",
region: "eu-central-1",
paths: ['/']
}
]
}
});
and somewhere else:
import Api from '#aws-amplify/api-rest';
Api.get('PetStore', '/pets', {})
.then(response => {
console.log(response)
}).catch(error => {
console.log(error);
});
But, when executed, I get always the same error:
API PetStore does not exist
Any idea? Remember that:
API Already exist
I don't want to use Amplify CLI to create AWS resources
I'd like to add that #Deiv was correct to suggest API.configure(), this worked for me. After trying amplify pull and amplify push I still received the error API <api-name> does not exist.
So my code now looks like this:
import Amplify, { API } from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
API.configure(awsconfig);
I am using npm package: aws-amplify 3.3.21
I had this same issue and I managed to resolve it by configuring the exports on the "Api" object directly:
API.configure(aws_exports);
Previously it worked for me with just setting it on Amplify.configure, but it seems a newer version of Amplify requires it on the sub module itself.
Some more bits and pieces can be found here in this long-standing issue (in which the same issue popped up for Auth, but I applied the same to both in my case and it fixed it): https://github.com/aws-amplify/amplify-js/issues/4315
You need to call API.configure() after Amplify.configure is called, or else your API setup won't be applied, hence it returns API PetStore does not exist
import Amplify, { API } from 'aws-amplify'; // this part depends on which Amplify you are using. but make sure to import API
Amplify.configure({
Auth: {
...
},
API: {
endpoints: [
{
name: "PetStore", // name of the API in API Gateway console
endpoint: "https://XXX.execute-api.eu-central-1.amazonaws.com/dev",
region: "eu-central-1",
paths: ['/']
}
]
}
});
// Call this
API.configure(); // no awsconfig required as you have set your own
We changed the version of aws-amplify from 3 back to a previous version "aws-amplify": "^2.2.2" in package.json and that resolved it.
Think version 3 broke the manual configuration of aws-amplify.
Try changing the version to a previous version you know worked.
API * does not exist usually means you haven't pushed the REST API you created. If you can't use amplify push have you manually created and amplify API through the console?

AWS .NET Core Lambda - Image Upload Broken

I'm in the process of building a Web API with AWS Lambda using .NET Core.
I have run into a problem, where the code piece below work as expected on my Windows machine (Echo the image back), but when deployed to AWS Lambda, the returned image is broken. After further investigation, the echoed back file's size is nearly double the size of the sending file when deployed on AWS?
[HttpPost]
public async Task<IActionResult> Post(IFormFile file)
{
using (var tmpStream = new MemoryStream())
{
await file.CopyToAsync(tmpStream);
var fileExtension = Path.GetExtension(file.FileName);
return File(tmpStream.ToArray(), file.ContentType);
}
}
Am I missing some configuration or overlooking something? AWS Gateway??
(I'm testing the issue via Postman)
Did you look at the contents of the file? My guess it is the html error result or something.
In this blog post (Serverless ASP.NET Core 2.0 Applications) they mention:
If your web application displays images, we recommend you serve those images from Amazon S3. This is more efficient for returning static content like images, Cascading Style Sheets, etc. Also, to return images from your Lambda function to the browser, you need to do extra configuration in API Gateway for binary data.
See API Gateway for binary data for how to configure that.
Incase anyone is looking for a solution, in addition to adding "multipart/form-data" as binary media type in the API Gateway settings, you need to add a model in the method request body of the resource.
Details can be found at https://github.com/aws/aws-lambda-dotnet/issues/635#issuecomment-616226910
Steps:
Add "multipart/form-data" as binary type in LambdaEntryPoint.cs file (if that is how it is named).
public class LambdaEntryPoint : APIGatewayProxyFunction
{
/// <summary>
/// The builder has configuration, logging and Amazon API Gateway already configured. The startup class
/// needs to be configured in this method using the UseStartup<>() method.
/// </summary>
/// <param name="builder"></param>
protected override void Init(IWebHostBuilder builder)
{
RegisterResponseContentEncodingForContentType("multipart/form-data", ResponseContentEncoding.Base64);
builder.UseStartup<Startup>();
}
}
Add BinaryMediaTypes in the settings section of the AWS API Gateway as shown
here - BinaryMediaTypes in API Gateway.
Create a new model for the API Gateway with the configuration as
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "MediaFileUpload",
"type": "object",
"properties": {
"file": { "type": "string" }
}
}
Update the method request step by adding an entry in "Request Body" using the created model as a content type of "multipart/form-data"( as shown in API Gateway Resource).
Make sure that you deploy the API so that the changes take effect.
EDIT: Added code, and additional steps for clarity, as comment by #JeremyCaney
Add BinaryMediaTypes "multipart/form-data" in the settings section of the AWS API Gateway. Deploy the Api (If you have done it before, do it again after changing the settings).

How to convert apiDoc to postman collection?

I have a nodejs project with many requests implemented and well documented by apiDoc, and I want to create a Postman collection from it!
> example:
/**
* #api {GET} config/updates Updates - Get the latest event updates
* #apiGroup Config service
* #apiDescription This api endpoint provides the latest updates that need to be fetched by the client. It provides
* an array of events, based on either the latestupdate (timestamp) param, or a configured interval (currently default to 1 minute.
...
..
*/
It is possible to create from apiDoc a postman collection?
You can export your apiDoc to Swagger and then import it to Postman.
1.Export to Swagger
Install this npm-package
npm install apidoc-swagger -g
apidoc-swagger -i example/ -o doc/ (example is the input and doc is the output)
2.Import in Postman
Postman supports swagger files so you can import it without issues you can read about it here read 'Importing swagger' section.
The npm package may not work because it seems outdated.

Generate swagger-api with existing vert.x project

I have an existing vert.x project which became too heavyweight and intransparent.*
To replace it I am checking for several options, one of those being swagger.
Does anyone know an opensource lib which can create a swagger-api from vert.x?
I'm not aware of something like that. The only vertx-swagger integration does exactly the opposite: generates Vertx router based on Swagger configuration:
https://github.com/phiz71/vertx-swagger
What you can do is generate all routes using this solution: List all registered routes in Vertx
Then add them manually to Swagger Editor, and finally generate your new APIs with Swagger Codegen
Do mind that rewriting you application into another language or framework probably won't solve your problems. NodeJS is not as typesafe as Vertx, and SpringBoot is not as concurrent as Vertx. But if you don't need typesafety or concurrency, both are viable options, of course.
Here's an open source project (for the JVM) that generates a Swagger/OpenAPI specification from your existing Vert.x router:
https://github.com/outofcoffee/vertx-oas
(Disclosure: It's my open source project)
Example usage:
// your normal Vert.x Web Router with paths etc.
Router router = Router.router(vertx);
router.post("/users").handler( routingContext -> { /* etc... */ });
router.get("/users/:userId").handler( routingContext -> { /* etc... */ });
// publish the Swagger/OpenAPI specification to a URL
RouterSpecGenerator.publishApiDocs(router, "/api/spec");
You can obtain YAML or JSON versions of the specification by adding the appropriate file extension.
For example, fetching /api/spec.yaml would produce:
openapi: "3.0.1"
info:
title: "Vert.x APIs"
description: "This specification was generated from a Vert.x Web Router."
paths:
/users:
post:
parameters: []
/users/{userId}:
get:
parameters:
- name: "userId"
required: true
allowEmptyValue: false

ASP.NET Core Swagger uses incorrect json url when web application is hosted in a subdirectory

I followed these instructions to add swagger to my ASP.NET Core application.
It works fine when I host it as a root website but when I host the app as an alias on an existing website, say myserver.com/myapp, swagger will look for swagger.json at an incorrect URL and report: *Can't read swagger JSON from https://myserver.com/swagger/v1/swagger.json. It should instead use https://myserver.com/myapp/swagger/v1/swagger.json.
The message I get is:
Can't read swagger JSON from https://myserver.com/swagger/v1/swagger.json
How can I configure swashbuckle/swagger to use the application base path and look for the swagger.json file at the right place?
I'm hosting on IIS.
The version of swashbuckle is:
"Swashbuckle": "6.0.0-beta902"
I suspect that I'll have to add something to the app.UseSwaggerUi() in the Configure method in Startup.cs but I'm not sure what.
Startup Configure:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
// Enable middleware to serve generated Swagger as a JSON endpoint
app.UseSwagger();
// Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
app.UseSwaggerUi();
}
You can use the ASPNETCORE_APPL_PATH environment variable to get the application basepath.
app.UseSwaggerUI(c =>
{
string basePath = Environment.GetEnvironmentVariable("ASPNETCORE_APPL_PATH");
if (basePath == null) basePath = "/";
c.SwaggerEndpoint($"{basePath}swagger/v1/swagger.json", "My API");
});
I ended up specifying the endpoint explicitly:
app.UseSwagger();
app.UseSwaggerUi(c =>
{
c.SwaggerEndpoint($"/swagger/v1/swagger.json", "MyAPI documentation");
//c.SwaggerEndpoint($"/myapi/swagger/v1/swagger.json", "MyAPI documentation");
});
I've been fooling around with hosting the Web API in IIS and in IIS Express, and I end up having to swap out the endpoint depending on where I am hosting the app.