Skip to content
This repository has been archived by the owner on Jan 21, 2024. It is now read-only.

Question: Possible to exclude endpoints when converting OAS > RAML? #81

Closed
Serdarrr opened this issue Aug 8, 2020 · 10 comments
Closed
Labels
question Further information is requested

Comments

@Serdarrr
Copy link

Serdarrr commented Aug 8, 2020

Library version used
0.5.0

Language library used with
Java

Description
Hi great plugin, but im having a hard time figuring out on how to achieve the following and I appreciate if you could help me out.

I would like to parse a OpenApi 3 JSON document (using Springdoc) and output a single API endpoint in a RAML file, because the system I'm using displays a swagger documentation based on a single endpoint config RAML file (see below desired output). Also is their a way to not have auto prefixed amf- variables in RAML? e.g. amf-serverDescription, amf-summary, amf-tags. I want this to be default variables (description, summary, tags).

Code

public static void translateFromUrl(String url) throws InterruptedException, ExecutionException {
    // Parse OAS 3 json to WebApiDocument
    WebApiDocument doc = (WebApiDocument) Oas30.parse(url).get();
    // Resolve parsed model (optional)
    final WebApiBaseUnit resolved = Raml08.resolve(doc).get();
    // Generate RAML 0.8 file
    String fpath = "file://api-endpoints.raml";
    Raml08.generateFile(resolved, fpath).get();
}

Input: Open Api 3 doc

{
   "openapi":"3.0.1",
   "info":{
      "title":"OpenAPI definition",
      "version":"v1"
   },
   "servers":[
      {
         "url":"http://localhost:8080",
         "description":"Generated server url"
      }
   ],
   "paths":{
      "/api/pages":{
         "get":{
            "tags":[
               "page-controller"
            ],
            "summary":"getAllPages() summary..",
            "operationId":"getAllPages",
            "responses":{
               "default":{
                  "description":"default response",
                  "content":{
                     "application/json":{
                        "schema":{
                           "$ref":"#/components/schemas/Page"
                        }
                     }
                  }
               }
            }
         }
      },
      "/api/users":{
         "get":{
            "tags":[
               "user-controller"
            ],
            "summary":"getAllUsers() summary..",
            "operationId":"getAllUsers",
            "responses":{
               "default":{
                  "description":"default response",
                  "content":{
                     "application/json":{
                        "schema":{
                           "$ref":"#/components/schemas/User"
                        }
                     }
                  }
               }
            }
         }
      }
   },
   "components":{
      "schemas":{
         "Page":{
            "type":"object",
            "properties":{
               "number":{
                  "type":"integer",
                  "format":"int32"
               },
               "name":{
                  "type":"string"
               },
               "content":{
                  "type":"string"
               }
            }
         },
         "User":{
            "type":"object",
            "properties":{
               "name":{
                  "type":"string"
               },
               "username":{
                  "type":"string"
               },
               "password":{
                  "type":"string"
               }
            }
         }
      }
   }
}

Output: RAML 0.8

title: OpenAPI definition
baseUri: http://localhost:8080
(amf-serverDescription): Generated server url
version: v1
/api/pages:
  get:
    displayName: getAllPages
    (amf-summary): getAllPages() summary..
    (amf-tags):
      - page-controller
    (amf-defaultResponse):
      default:
        description: default response
        body:
          application/json:
            formParameters:
              number:
                type: integer
                required: false
              name:
                type: string
                required: false
              content:
                type: string
                required: false
/api/users:
  get:
    displayName: getAllUsers
    (amf-summary): getAllUsers() summary..
    (amf-tags):
      - user-controller
    (amf-defaultResponse):
      default:
        description: default response
        body:
          application/json:
            formParameters:
              name:
                type: string
                required: false
              username:
                type: string
                required: false
              password:
                type: string
                required: false

Desired RAML output

title: OpenAPI definition
baseUri: http://localhost:8080
description: Generated server url
version: v1
/api/users:
  get:
    displayName: getAllUsers
    summary: getAllUsers() summary..
    tags:
      - user-controller
    defaultResponse:
      default:
        description: default response
        body:
          application/json:
            formParameters:
              name:
                type: string
                required: false
              username:
                type: string
                required: false
              password:
                type: string
                required: false
@postatum
Copy link
Contributor

postatum commented Aug 10, 2020

Hi @cytor!

Regarding the endpoints question - after you resolve the parsed document with Raml08.resolve, here's what you could do:

  • Get a list of endpoints with resolved.encodes.endPoints() (though resolved would have to be WebApiDocument);
  • Pick endpoints you like into a separate array/list by inspecting their path, name, something else. Here's the API;
  • Replace existing endpoints in the parsed model by the ones you like with resolved.encodes.withEndPoints();
  • Generate RAML.

Regarding amf prefixes - there's no way to avoid these as OAS 3.0 nodes summary, tags, defaultResponse aren't valid in RAML. You could try to replace these with nodes that are present in both OAS 3.0 and RAML (e.g. description instead of summary) and see how it works.

@postatum postatum reopened this Aug 10, 2020
@postatum postatum added the question Further information is requested label Aug 10, 2020
@Serdarrr
Copy link
Author

Hi @postatum,

Thank you for your reply and guidance, I managed to get it to work 👍

    public static void translateFromUrl(String url, String endPointName) throws InterruptedException, ExecutionException {
        // Parse Swagger 3 document to WebApiDocument
        WebApiDocument doc = (WebApiDocument) Oas30.parse(url).get();

        // Filter out specific API endpoints of current endpoint list based on API path names
        if (!endPointName.isEmpty()) {
            // Get the API instance
            WebApi api = (WebApi) doc.encodes();
            // Create new endpoint list based on path that ends with endpoint name 
            List<EndPoint> newList = api.endPoints().stream()
                    .filter(endPoint -> endPoint.relativePath().endsWith(endPointName)).collect(Collectors.toList());
            api.withEndPoints(newList);
        }

        // Resolve parsed model
        WebApiBaseUnit resolved = Raml08.resolve(doc).get();

        // Generate RAML 0.8 file
        String fpath = "file://api-endpoints.raml";
        Raml08.generateFile(resolved, fpath).get();
    }

@Serdarrr Serdarrr reopened this Aug 10, 2020
@Serdarrr
Copy link
Author

I have noticed that when generating file for Raml 0.8, the parameter descriptions are not present, but they are in Raml 1.0. Do I need to enable for Raml08 in order to see the descriptions or is it a bug?

@postatum
Copy link
Contributor

postatum commented Aug 11, 2020

I have noticed that when generating file for Raml 0.8, the parameter descriptions are not present, but they are in Raml 1.0. Do I need to enable for Raml08 in order to see the descriptions or is it a bug?

Hello again.

Can you provide more details please? In particular - input and RAML 0.8, RAML 1.0 output.

@Serdarrr
Copy link
Author

Serdarrr commented Aug 11, 2020

Hello, here it is. I'm also using the code I mentioned in my previous reply for parsing (and switched between Raml08 and Ram10 classes). As you can see below, description is missing for the parameter name def in RAML 8.0.
About amf prefixes, is there a way to remove it before generating RAML file? Because the CMS I'm using, does not recognize these amf variables and sees them as invalid, but If I remove them manually it becomes valid.

Input

    @GetMapping(path = "users")
    @Operation(summary = "getAllUsers() summary..",
    responses = @ApiResponse(content = @Content(mediaType = "application/json", schema = @Schema(implementation = User.class)))) // Output response body type
    public List<User> getAllUsers(
            @Parameter(name = "def", description = "default parameter description..") String def
    ) {
        return userService.getAllUsers();
    }

Output RAML 0.8

#%RAML 0.8
title: API Endpoints
baseUri: http://localhost:8080
(amf-serverDescription): Generated server url
version: v1
/api/users:
  get:
    displayName: getAllUsers
    (amf-summary): getAllUsers() summary..
    (amf-tags):
      - user-controller
    queryParameters:
      def:
        type: string
        required: true
    (amf-defaultResponse):
      default:
        description: default response
        body:
          application/json:
            formParameters:
              name:
                type: string
                required: false
              username:
                type: string
                required: false
              password:
                type: string
                required: false

Output RAML 1.0

#%RAML 1.0
title: API Endpoints
baseUri: http://localhost:8080
(amf-serverDescription): Generated server url
version: v1
/api/users:
  get:
    displayName: getAllUsers
    (amf-summary): getAllUsers() summary..
    (amf-tags):
      - user-controller
    queryParameters:
      def:
        **description: default parameter description..**
        required: true
        type: string
    (amf-defaultResponse):
      default:
        description: default response
        body:
          application/json:
            type: object
            additionalProperties: true
            properties:
              name:
                type: string
                required: false
              username:
                type: string
                required: false
              password:
                type: string
                required: false

@postatum
Copy link
Contributor

@cytor, sorry, I don't understand what's happening in your input - it seems to be too framework-ish.

I guess you try to manually add a query param. If so, I think it should be done through Request.withQueryParameters(). Request is at endPoints[index].operations[index].request (or requests[index].

@Serdarrr
Copy link
Author

Serdarrr commented Aug 11, 2020

@postatum Haha, my bad. Im using springdoc (swagger 3) for generating a OpenApi 3 doc in springboot framework. But this isn't relevant (I think). The OpenApi 3 Json output is as followed for the API endpoint users that's being converted to Raml output. As you can see in the /api/users path, the parameter def has a description but I don't see it when converting to Raml08.

Input

{
   "openapi":"3.0.1",
   "info":{
      "title":"API Endpoints",
      "version":"v1"
   },
   "servers":[
      {
         "url":"http://localhost:8080",
         "description":"Generated server url"
      }
   ],
   "paths":{
      "/api/users":{
         "get":{
            "tags":[
               "user-controller"
            ],
            "summary":"getAllUsers() summary..",
            "operationId":"getAllUsers",
            "parameters":[
               {
                  "name":"def",
                  "in":"query",
                  "description":"default parameter description..",
                  "required":true,
                  "schema":{
                     "type":"string"
                  }
               }
            ],
            "responses":{
               "default":{
                  "description":"default response",
                  "content":{
                     "application/json":{
                        "schema":{
                           "$ref":"#/components/schemas/User"
                        }
                     }
                  }
               }
            }
         }
      }
   },
   "components":{
      "schemas":{
         "Page":{
            "type":"object",
            "properties":{
               "number":{
                  "type":"integer",
                  "format":"int32"
               },
               "name":{
                  "type":"string"
               },
               "content":{
                  "type":"string"
               }
            }
         },
         "User":{
            "type":"object",
            "properties":{
               "name":{
                  "type":"string"
               },
               "username":{
                  "type":"string"
               },
               "password":{
                  "type":"string"
               }
            }
         }
      }
   }
}

@postatum
Copy link
Contributor

@cytor thanks for the code. It seems to be a bug in our dependency lib. I've reported the issue and moved further bug discussion here #82.

Regarding amf-prefixed fields: I can't think of a way other than parsing resulting YAML string with some YAML parser and editing fields' names manually.

@Serdarrr
Copy link
Author

@postatum I see. I will wait for it to resolve. I was able to locate the fields through the WebApi object and remove them.

@postatum
Copy link
Contributor

postatum commented Nov 3, 2020

I'm closing this issue as it's inactive. Feel free to reopen it if needed.

@postatum postatum closed this as completed Nov 3, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants