mkrufky
mkrufky

Reputation: 3388

Converting a Swagger YAML file to JSON from the command line

I'd like to convert a Swagger YAML file to JSON from the command line. The plan is to use this command line during a CI job. I've searched on google and found many solutions, but most of them use Python or Ruby, which I'd prefer not to use. For example: http://www.commandlinefu.com/commands/view/12218/convert-yaml-to-json

I'd like to do this without using Python or Ruby, and I'd also like to be able to control the leading whitespace when formatting the JSON to match exactly the JSON that is output from Swagger's editor.swagger.io editor, when you choose File -> Download JSON

All this means is that I'd like the whitespace padding to be four spaces, like so:

{
    "swagger": "2.0",
    "info": {
        "title": "API TITLE",

I haven't tried the Python method in the link above, but the Ruby method uses two space whitespace padding. Perhaps there is a way to control that, but I don't want to use Ruby or Python in this solution anyway.

I'm sure that there are many "correct" answers to this question. I am looking for the solution that is most elegant with the least number of dependencies. Ideally, a diff of the resulting JSON file against a JSON file generated by the editor.swagger.io should be empty.

Upvotes: 38

Views: 75616

Answers (8)

Nashev
Nashev

Reputation: 635

For a gradle with Kotlin, I've written in my build.gradle.kts:

import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import java.nio.file.Path

And then in a some task like compileJavacode for conversion:

val compileJava: Task by tasks.getting {
  val openApiDir = "${rootProject.projectDir}/openapi"    
  val json: JsonNode? = ObjectMapper(YAMLFactory())
    .readTree(Path.of("$openApiDir/openapi.yaml").toFile())
  ObjectMapper().writerWithDefaultPrettyPrinter()
    .writeValue(Path.of("$openApiDir/openapi.json").toFile(), json)
}

Upvotes: 0

Liel
Liel

Reputation: 482

I think that you are looking for the swagger-codegen (now OpenApi-generator) functionality:

Running

swagger-codegen generate -i swagger.yaml -l swagger

will out put a swagger.json in the same location.

Update For CI: If you can install it on your build machine- good for you. If you can't - the github page has a link to a docker image with a nodejs server is available (to convert using a curl command as suggested in a different answer).

Update For Docker: If you use Docker, try swaggerapi/swagger-codegen-cli, there is an example for docker-compose that might help a few answers down by Fabian & ckeeney.

Update about OpenApi:

This question is about swagger, and a few years old. If you're just starting to use Swagger you should switch to OpenApi instead, and if you have existing swagger files, i suggest migrating.

Upvotes: 28

0llie
0llie

Reputation: 8885

I'd use https://openapi-generator.tech/

It's an npm install (I just used it locally npm install @openapitools/openapi-generator-cli) and then

npx @openapitools/openapi-generator-cli generate -i source.yaml -g openapi -o outputdir

Upvotes: 3

Sebastian
Sebastian

Reputation: 928

Another possibility to convert a swagger.yml file to swagger.json is a NPM package called swagger-cli.

npm install -g swagger-cli

Then you can convert a yml to json file:

swagger-cli bundle -o api-spec.json api-spec.yml

Upvotes: 13

kuzdu
kuzdu

Reputation: 7524

For version swagger-codegen 3.0.4

Use

swagger-codegen generate -i my_yaml.yaml -l openapi

to get a .json.

Upvotes: 9

ckeeney
ckeeney

Reputation: 1386

swagger-codegen cli interface

As Liel has already pointed out, you can run

swagger-codegen generate -i swagger.yaml -l swagger

Docker

If you use Docker, then I suggest you try swaggerapi/swagger-codegen-cli.

You can generate a json file using docker with the following command:

docker run -v ./docs:/docs swaggerapi/swagger-codegen-cli generate -i /docs/swagger.yaml -l swagger -o /docs

I like to setup a docker-compose.yml to "alias" this command for easy reuse:

version: "2"
services:
  gen-swagger:
    volumes:
      - ./docs:/docs
    image: swaggerapi/swagger-codegen-cli
    command: generate -i /docs/swagger.yaml -l swagger -o /docs

And now I can just run docker-compose run gen-swagger

Upvotes: 11

fehguy
fehguy

Reputation: 6824

You can use the online swagger codegen project to do this:

curl -X POST --header "Content-Type: application/json" --header "Accept: application/json" -d "{
  \"spec\": {}
}" "https://generator.swagger.io/api/gen/clients/swagger-yaml"

Put the value of your swagger definition in the spec object. You'll get a link to download the converted & validated spec, in yaml format.

For options, take a look here:

http://generator.swagger.io/

Upvotes: 6

mkrufky
mkrufky

Reputation: 3388

Using yamljs:

yaml2json swagger.yaml -p -i4

The output from this command diff'd against the JSON output from editor.swagger.io produces an empty diff.

This is indeed what I'm looking for, but it brings in a huge dependency (node). I'm hoping for something even lighter, yet equally as elegant as this.

Upvotes: 11

Related Questions