Is there a way to stop Autorest.Powershell from flattening response objects?

454 views Asked by At

I have a response object in my swagger.json file that includes a nested object as one of its fields. When I use Autorest.Powershell to generate a client for this API, it flattens the nested object. So when the service returns the following response:

{
  "code": 200,
  "status": "OK",
  "data": {
    "FileName": "gameserver.zip",
    "AssetUploadUrl": "https://example.com"
  }
}

my Autorest.Powershell client returns a flattened object like this:

{
  "code": 200,
  "status": "OK",
  "dataFileName": "gameserver.zip",
  "dataAssetUploadUrl": "https://example.com"
}

Is there some sort of configuration setting I can use to disable this behavior?

Here are the relevant portions of my swagger.json file, if it helps:

"definitions": {
  "GetAssetUploadUrlResponse": {
    "type": "object",
    "properties": {
      "AssetUploadUrl": {
        "description": "The asset's upload URL.",
        "type": "string"
      },
      "FileName": {
        "description": "The asset's file name to get the upload URL for.",
        "type": "string"
      }
    },
    "example": {
      "FileName": "gameserver.zip",
      "AssetUploadUrl": "https://example.com"
    }
  }
},
"responses": {
  "GetAssetUploadUrlResponse": {
    "description": "",
    "schema": {
      "type": "object",
      "properties": {
        "code": {
          "type": "integer",
          "description": "The Http status code. If X-ReportErrorAsSuccess header is set to true, this will report the actual http error code."
        },
        "status": {
          "type": "string",
          "description": "The Http status code as a string."
        },
        "data": {
          "$ref": "#/definitions/GetAssetUploadUrlResponse"
        }
      },
      "example": {
        "code": 200,
        "status": "OK",
        "data": {
          "FileName": "gameserver.zip",
          "AssetUploadUrl": "https://example.com"
        }
      }
    }
  }
}
1

There are 1 answers

0
zahical On BEST ANSWER

There are several ways, none of which is really straightforward (as, I'm starting to believe, is the case with most things AutoRest-related; sorry, couldn't resist :-P ).

There are three semi-official ways. Semi-official here means they are based on public AutoRest mechanism but are not themselves documented. Being semi-official, they might only work with certain versions of AutoRest components, so, here are the ones I used (from autorest --info):

  • @autorest/core (3.0.6369)
  • @autorest/modelerfour (4.15.414)
  • @autorest/powershell (3.0.421)

Finally, here are the relevant parts of AutoRest's code base: inline properties plug-in and configuration directive definition

inlining-threshold setting

This setting control the maximum number of properties an inner object could have for it to be considered eligible for inlining. You can set it either on the command line or in the "literate config" .md file.

```yaml
inlining-threshold: 0
```

In theory, setting this to 0 should prevent any inner member's properties from being inlined, however the plug-in has a hard-coded exception that if the inner object is in a property that's itself named properties then the limit is ignored and it's still flattened.

definitions:
  SomeSchema:
    type: "object"
    properties:
      detail_info: # <-- threshold honored
        $ref: "#/definitions/InfoSchema"
      properties: # <-- this is always flattened because of its special name
        $ref: "#/definitions/OtherSchema"

no-inline directive

The PowerShell AutoRest plug-in also defines a custom directive that is used to specify that certain schemas should never be inlined. Using "literate config", it goes like

```yaml
directive:
- no-inline:
  - OtherSchema
  - ThirdSchema
```

The pros of this approach are that the no-inline directive overrides the "always inline properties in a property named properties" exception mentioned above, so it can be used to alleviate the problem.

The cons are that all schema names should be listed explicitly. (It seems the directive should also support Rx name expression but I couldn't get no-inline: ".*" to work)

Low-level transform

This is approach disables inlining unconditionally in all cases, however it is coupled to the specific internal code model used by AutoRest. (In principle, the model should be stable, at least within major versions). It also relies on the PowerShell plug-in using a specific (non-contractual) property to flag schemas excluded from inlining.

```yaml
directive:
- from: code-model-v4-no-tags
  where: $.schemas.objects.*
  transform: |
    $.language.default['skip-inline'] = true;
```