Azure / autorest

OpenAPI (f.k.a Swagger) Specification code generator. Supports C#, PowerShell, Go, Java, Node.js, TypeScript, Python
MIT License
4.62k stars 739 forks source link

[Question] How to define `$ref` to definitions in other files when overwriting definition #4237

Open archerzz opened 3 years ago

archerzz commented 3 years ago

Before asking the question:

Problem

I have a definition which has excessive properties. So I want to re-write it as follow, using where-model directives.

 - where-model: DdosProtectionPlan
    transform: >
      return {
        "description": "A DDoS protection plan in a resource group.",
        "x-ms-azure-resource": true,
        "properties": {
          "properties": {
            "x-ms-client-flatten": true,
            "$ref": "#/definitions/DdosProtectionPlanPropertiesFormat",
            "description": "Properties of the DDoS protection plan."
          },
          "etag": {
            "readOnly": true,
            "type": "string",
            "description": "A unique read-only string that changes whenever the resource is updated."
          }
        },
        "allOf": [
            {
              "$ref": "./network.json#/definitions/Resource" ## PROBLEM!
            }
        ]
      }

The problem is that when using autorest to generate the codes, I got the following error. [Note]: If I modify the original swagger JSON file, the generation is OK.

Error: $ref to original location './network.json#/components/schemas/Resource' is not found in the new refs collection

I tried many alternatives, and it seems that when where-model directive is being processed, the reference key is changed to a global absolute value. If I changed the $ref to file:///C:/Users/mingzhehuang/workspaces/azure/azure-rest-api-specs/specification/network/resource-manager/Microsoft.Network/stable/2021-02-01/network.json#/definitions/Resource, the generation is fine.

Question

Is there a way I can safely refer to definitions in other files when overwriting the definition? Thanks.

timotheeguerin commented 3 years ago

Yeah, I think this is due to how references are expanded at the beginning but not again later. you can use $documentPath to make the full reference

"$ref": "$documentPath/../network.json#/definitions/Resource"

We could maybe do another crawl of the reference after the transform step

archerzz commented 3 years ago

Thanks @timotheeguerin !

It would be better to re-calculate the $ref if the given value is not found. That will make the customization much easier.

archerzz commented 3 years ago

@timotheeguerin Do you want me close this issue, or keep it open as a feature request?

timotheeguerin commented 3 years ago

We can keep this issue for it. I tried adding the crawling of reference after. The current issue is that when it crawl reference it might also add new files if this is a reference to another file that wasn't referenced before. Then it would need to make sure it loads it and we need to decide what we do with it. Do we rerun the previous stages on it(transforms) or we just act like it is already good and keep going.