Generate Swagger YAML Open API Spec programmatically from WSDL/XML - rest

I have a SOAP API already defined via WSDLs. Is there any tool that I can use to convert WSDL to Open API Swagger documents?
I am assuming that I would need to write custom code to to create a Swagger 3.0 Open API YAML specification from an XML.
XML:
<country>
<name>ABC</name>
<population>100</population>
<political_system>
<system_type>Democracy</system_type>
<legislature>bicameral</legislature>
</country>
Open API Definition:
openapi: "3.0.0"
info:
version: 1.0.0
title: SysCountry
servers:
- url: http://localhost:5595/api/
paths:
/Country:
get:
tags:
-countries
responses:
'200':
description:List of countries
content:
application/json:
schema:
$ref:"#/components/schemas/Countries
post:
summary:Create a country
tags:
-Conuntries
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Country'
responses:
'201':
description: Null response
components:
schemas:
Country:
type: object
required:
- name
properties:
name:
type: string
population:
type: integer
political_system:
type: object
properties:
system_type:
type: string
legislature:
type:string
Countries:
type: array
items:
$ref: "#/components/schemas/Country"
Is there any .NET C# library that can be used to create YAML documents programmatically (maybe something similar to an XMLDocument)?

I know this is an old question, but, I was looking for the same thing and couldn't find a decent, hassle free solution, so maybe this answer can help someone else too.
The easiest way I have found to convert a WSDL to YAML is using APIMATIC (www.apimatic.io).
A free account can convert as many WSDLs (or other formats) as you want, there's no need for a subscription.
Cheers.

There's YamlDotNet - https://github.com/aaubry/YamlDotNet
You can create a YamlStream + YamlDocument and build your document from there, similar to using XmlDocument.
Another approach is to create classes to represent the swagger document and use the serialization API to generate the document, similar to using XmlSerializer.

Related

Custom rule for application/problem+json using Stoplight Spectral CLI

I'm trying to make a custom rule based on the unkown-error-format that can be found here here. Using this Open API document as an example:
openapi-generated.yaml
openapi: 3.0.3
info:
title: API
version: 1.0.0
servers:
- url: https://api.com/
paths:
/:
get:
tags: []
summary: Your GET endpoint
description: Your GET endpoint
operationId: get-endpoint
responses:
"500":
description: Error
content:
application/json:
schema:
properties:
errorDescription:
type: string
and this rule set:
.spectral.yml
extends:
- https://raw.githubusercontent.com/openapi-contrib/style-guides/master/apisyouwonthate.yml
rules:
unknown-error-format: error
When running
spectral lint --ruleset .spectral.yml openapi-generated.yaml
I was expecting an error to be returned, because the 500 response content is application/json and not one of the allowed values application/vnd.api+json, application/problem+xml, and application/problem+json.
Instead no errors are found:
No results with a severity of 'error' or higher found!
I experimented with some other Spectral core functions that should make the linter return an error, but it does not. I suspect the expression in given is not returning the right result, internally.
Additionally, I tried using this JSON Path Demo to check if the output array with "application/json" is returned for the path in the rule's given. It does.
Is there a problem with this rule or am I doing something wrong?
I'm using Spectral version 6.1.0.
Thanks in advance.

Swagger Editor - Additional Properties Error

I'm just starting to use Swagger Editor/OpenAPI 3 spec and so it's not going good so far. I have installed and running Swagger Editor v. 3.15.2 on my local machine.
This is the yaml I have so far:
openapi: "3.0.0"
info:
version: 1.0.0
title: Test
paths:
/object:
post:
summary: Create an object
operationId: createObject
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/Object"
responses:
'201':
description: Created
components:
schemas:
Object:
required:
- name
- description
properties:
name:
type: string
description:
type: string
And it's displaying this error:
Errors
Resolver error
e is undefined
Structural error at paths./object
should NOT have additional properties
additionalProperty: responses
Jump to line 6
Structural error at paths./object.post
should have required property 'responses'
missingProperty: responses
Jump to line 7
I have ensured that I am using two spaces for all the indents. When I copied the yaml from the editor and put it into Notepad++ it looked fine. I also pasted it into another editor and noticed that it only used line feeds and not carriage returns. I updated it to use both and still get the same error.
I have looked at other questions with the same problem but none of the solutions worked for me. So, not sure what I'm doing wrong. Any guidance is greatly appreciated.
You have a small indentation problem.
Add one indentation level to
responses:
'201':
description: Created
So that you then have:
openapi: "3.0.0"
info:
version: 1.0.0
title: Test
paths:
/object:
post:
summary: Create an object
operationId: createObject
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/Object"
responses:
'201':
description: Created
components:
schemas:
Object:
required:
- name
- description
properties:
name:
type: string
description:
type: string

Is it possible to reference a single path and method in OpenAPI 3?

Suppose I have an OpenAPI 3 document describing API Foo as follows:
openapi: 3.0.0
info:
version: '1'
title: Foo
paths:
/foo:
get:
responses:
200:
description: A Foo
post:
responses:
201:
description: Foo created
In another OpenAPI document for API Bar, I would like to reference only the GET /foo operation from API Foo. The OpenAPI docs talk a little about referencing a whole path. However, if I do the following:
openapi: 3.0.0
info:
version: '1'
title: Bar
paths:
/foo:
$ref: 'foo.yaml#/paths/~1foo'
I naturally get both the GET and the POST in API Bar, since only the path is referenced, not the method.
I tried this:
openapi: 3.0.0
info:
version: '1'
title: Bar
paths:
/foo:
get:
$ref: 'foo.yaml#/paths/~1foo/get'
But this gives errors like should NOT have additional properties additionalProperty: $ref and should have required property 'responses' missingProperty: responses in various tools, so it doesn't seem to be supported.
Is there a way to accomplish this? I should note that the real request is much more complicated, hence the desire to de-duplicate. If possible I would like to avoid filling in many child objects of get with individual $refs.
OpenAPI doesn't have a way to $ref an individual operation (get/post/etc.), you can only $ref an entire path.
You can propose syntax enhancements in the OpenAPI Specification repository:
https://github.com/OAI/OpenAPI-Specification/issues

JHipster/OpenAPI: How do you do entity persistence?

I am trying to generate a project via JHipster with the OpenAPI option specified.
Create an OpenAPI specification file to define the entities and paths defining the application.
Create a JHipster .jdl file to specify the JHipster project parameters.
There are no entity definitions - this is intended to be provided by the OpenAPI file.
Execute JHipster (> jhipster import-jdl <file>.jdl).
Copy my OpenAPI file into src/main/resources/swagger/api.yml.
Execute OpenAPI sub-generator (> mvnw generate-sources).
This generates a microservice project, including the relevant OpenAPI classes generated by the OpenAPI sub-generator.
One very noticeable thing is missing: There is no code that deals with object persistence.
What do I need to do to provide this capability?
I know that JHipster has an entity sub-generator (entities can be defined in the JDL as well). This will generate a slew of code related to the defined entities, including persistence logic. However, this doesn't seem to fit well with the idea of defining entities in the OpenAPI specification file. I can't conceive of how these two techniques could possibly work together.
Has anyone done this?
Here are the relevant files for the curious:
[This is obviously an extremely simplistic application and persisting anything really makes little sense, but I'm providing it for illustration.]
jhipster.jdl:
application {
config {
packageName com.example
baseName echoMicroservice
applicationType microservice
serverPort 9100
buildTool maven
authenticationType jwt
clientPackageManager npm
serviceDiscoveryType no
messageBroker false
searchEngine false
databaseType sql
devDatabaseType mysql
prodDatabaseType mysql
cacheProvider hazelcast
enableHibernateCache false
clientFramework angularX
enableSwaggerCodegen true
}
}
echo-api.yml:
openapi: '3.0.1'
info:
title: 'echoMicroservice'
version: 0.0.1
servers:
- url: http://localhost:9100
description: Development server
- url: https://localhost:9100
description: Development server with TLS Profile
paths:
/random:
get:
summary: Returns a random message
description: Returns a random message
responses:
'200':
description: Random response
content:
application/json:
schema:
$ref: '#/components/schemas/Echo'
/echo:
post:
summary: Echoes a specified message
description: Echoes a specified message
requestBody:
description: Echo request
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Echo'
responses:
'200':
description: Echo response
content:
application/json:
schema:
$ref: '#/components/schemas/Echo'
components:
schemas:
Echo:
type: object
properties:
message:
type: string

AWS SAM - Multi level circular dependency between SAM's lambda and api resources

I am building a large application that has "static" resources (API, lambda LayerVersions, DynamoDB table etc) and "dynamic" resources (Lambda functions, Batch and SQS queues).
To neatly arrange this, I created multiple template files with some referring to others using SAM's AWS::Serverless::Application type.
In some of the "modules" (1 level deep nested stacks) I have lambdas that act as lambda proxies, and the API that they integrate with is declared in the StaticResourcesModule nested stack.
However these lambda need AWS::Serverless::Api's RestApiId property to know to which event to respond to.
The circular dependency happens because the Swagger 2.0 template that defines the AWS::Serverless::Api in the first place needs the Lambda's ARN (or lambda function's name and account number) to know which lambda implement what method (x-amazon-apigateway-integration 's uri attribute)
How can I pass to the API a reference to the lambda when the lambda themselves need a reference to the API's RestApiId property and both are in different stacks ?
The top level YAML template file looks like this:
Resources:
StaticResourcesModule:
Type: AWS::Serverless::Application
Properties:
Location: static_resources_module/template.yaml
DataFetchingModule:
Type: AWS::Serverless::Application
Properties:
Location: datafetching_module/template.yaml
Parameters:
MainApiId: !GetAtt StaticResourcesModule.Outputs.MainApiId
datafetching_module/template.yaml :
Parameters:
MainApiId:
Type: String
Description: >
Reference to the main api (AWS::Serverless::Api) resource.
Resources:
FetchingRequestsHandler:
Type: AWS::Serverless::Function
Description: Handles incoming requests [...]
Properties:
[...]
Events:
ApiPostNewRequestEvent:
Type: Api
Properties:
Method: post
Path: /fetching/low-priority
RestApiId: !Ref MainApiId
static_resources_module/template.yaml:
Parameters:
FetchingRequestsHandlerArn:
Type: String
Resources:
MainApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
DefinitionUri: api/swagger2_template.yaml
Outputs:
MainApiId:
Value: !Ref MainApi
Description: The Main API's RestApiId which to provide to the Lambda that require an API Event (lambda proxy)
api/swagger2_template.yaml:
/fetching/low-priority:
post:
# API integration, necessary.
x-amazon-apigateway-integration:
uri:
Fn::Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${FetchingRequestsHandlerArn}/invocations"