Code Monkey home page Code Monkey logo

autorest's Introduction

AutoRest

The AutoRest tool generates client libraries for accessing RESTful web services. Input to AutoRest is a spec that describes the REST API using the OpenAPI Specification format.

Release notes

Packages

Name Changelog Latest Next
Core functionality
autorest Changelog
@autorest/core Changelog
@autorest/modelerfour Changelog
Language generators
@autorest/csharp Changelog
@autorest/go Changelog
@autorest/java Changelog
@autorest/powershell Changelog
@autorest/python Changelog
@autorest/swift Changelog
@autorest/typescript Changelog
Internal packages
@autorest/codemodel Changelog
@autorest/common Changelog
@autorest/configuration Changelog
@autorest/extension-base Changelog
@azure-tools/extension Changelog
@azure-tools/codegen Changelog
@azure-tools/openapi Changelog
@azure-tools/deduplication Changelog
@azure-tools/datastore Changelog
@azure-tools/oai2-to-oai3 Changelog
@azure-tools/jsonschema Changelog

Support Policy

AutoRest is an open source tool -- if you need assistance, first check the documentation. If you find a bug or need some help, feel free to submit an issue

Getting Started using AutoRest image

View our docs readme as a starting point to find both general information and language-generator specific information

Contributing

Contributing guide

Check our internal developer docs to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to Autorest.

Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

autorest's People

Contributors

amarzavery avatar annatisch avatar bretjohnson avatar brjohnstmsft avatar daviwil avatar devigned avatar dsgouda avatar fearthecowboy avatar iscai-msft avatar jhendrixmsft avatar jianghaolu avatar joheredi avatar john-hart avatar lmazuel avatar markcowl avatar matthchr avatar mcardosos avatar nelsondaniel avatar nicklebedev37 avatar niklasgustafsson avatar ogail avatar olydis avatar sarangan12 avatar stankovski avatar tbombach avatar timotheeguerin avatar veronicagg avatar vishrutshah avatar xingwu1 avatar yugangw-msft avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

autorest's Issues

Specified non-successful status codes should throw HttpOperationException<> with specific schema

I have a controller called UserController with the following method:

[HttpPost]
[ResponseType(typeof(UserResource))]
[Route("api/v1/users")]
[ValidateRequest]
public async Task<HttpResponseMessage> AddUser(AddUserInput body) { }

ValidateRequest is my own attribute that returns a 400 Bad Request or a 422 Unprocessable Entity based on if the body parameter is null or the model state is invalid, respectively. They each provide their own resource in the response (ErrorResponse and ValidationResponse, respectively). I've configured Swashbuckle to generate the following Swagger json file:

"/api/v1/users": {
  "post": {
    "tags": [
      "User"
    ],
    "summary": "Adds a user.",
    "operationId": "User_AddUser",
    "consumes": [
      "application/json",
      "text/json"
    ],
    "produces": [
      "application/json",
      "text/json"
    ],
    "parameters": [
      {
        "name": "body",
        "in": "body",
        "description": "The body of the request.",
        "required": true,
        "schema": {
          "$ref": "#/definitions/AddUserInput"
        }
      }
    ],
    "responses": {
      "201": {
        "description": "The user was added successfully.",
        "schema": {
          "$ref": "#/definitions/UserResource"
        }
      },
      "400": {
        "description": "Request body is either empty or could not be properly parsed.",
        "schema": {
          "$ref": "#/definitions/ErrorResource"
        }
      },
      "422": {
        "description": "\r\nRequest body contains invalid fields. An error code will specify what is wrong with\r\nthe field. The possible validation error codes are:\r\n\r\n<table class='status-code-table'>\r\n<thead>\r\n    <tr>\r\n        <th>Code</th>\r\n        <th>Description</th>\r\n    </tr>\r\n</thead>\r\n<tbody>\r\n    <tr>\r\n        <td><code>missing_field</code></td>\r\n        <td>This means a required field on a resource has not been set.</td>\r\n    </tr>\r\n    <tr>\r\n        <td><code>invalid</code></td>\r\n        <td>This means the formatting of a field is invalid.</td>\r\n    </tr>\r\n    <tr>\r\n        <td><code>already_exists</code></td>\r\n        <td>\r\n            This means another resource has the same value as this field. This can happen in\r\n            resources that must have some unique key (such as Label names).\r\n        </td>\r\n    </tr>\r\n</tbody>\r\n</table>",
        "schema": {
          "$ref": "#/definitions/ValidationResource"
        }
      },
      "default": {
        "schema": {
          "$ref": "#/definitions/ErrorResource"
        }
      }
    },
    "deprecated": false
  }
}

My expectation is that the AutoRest generator would generate the following method signature:

public async Task<HttpOperationResponse<UserResource>> AddUserWithOperationResponseAsync(AddUserInput body, CancellationToken cancellationToken = default(System.Threading.CancellationToken)) {}

My other expectation is that if a non-successful status code is returned from the REST API, that this method would throw either a HttpOperationException<ErrorResource> or a HttpOperationException<ValidationResource>. Unfortunately, since I've specified that both 400 Bad Request and 422 Unprocessable Entity are possible responses, the generator thinks that they are valid (i.e. successful) operations so it's generating this method signature:

public async Task<HttpOperationResponse<object>> AddUserWithOperationResponseAsync(AddUserInput body, CancellationToken cancellationToken = default(System.Threading.CancellationToken)) {}

My issues with this:

  • The client loses all strongly typing of UserResource when it really is a successful call (i.e. 201 Created). I understand that if there are multiple success status codes with different resource types (schemas), then returning object makes sense.
  • Not only does a developer using the client have to wrap a try/catch around the operation to catch HttpOperationException<ErrorResource> because it's the default response, but they now also have to write their own logic when the method doesn't throw an exception in order to figure out what the response code is and then deserialize the response's content accordingly. It would be much easier if the developer could just catch HttpOperationException<ErrorResource> and HttpOperationException<ValidationResource> separately. And if the method returns without exception, they could assume they have a valid UserResource object.

Can the generator be changed (or an option added) so that all non-successful status codes returned from REST API throw a strongly-typed HttpOperationException<> based on the schema?

add support for "examples" in responses object

Including "examples" in a swagger spec results in an error

error: [ Fatal ] Error generating client model: Requested value 'examples' was not found.
Finished generating CSharp code for swagger.json.
Swagger example located here. Definition of example here for use in the response object defined here.

Error when generating C# code

I've been trying to get AutoRest to generate C# code from the official sample from Swagger.io. I get this error:

error: [FATAL] Error generating service model: The operation 'placeOrder' has a body parameter, but did not have a supported MIME type ('application/json') in its Consumes property.

Is that bug in AutoRest or the sample swagger file from swagger.io?

I also tried the Swagger from TheTVDB, where I get what is defiantly a bug in AutoRest:

error: [FATAL] Error generating service model: Object reference not set to an instance of an object.

Source for AutoRest.exe?

Good evening

it looks like the source for AutoRest.exe is not in this repository - searchinv for e.g. "CodeGenerator" (an commandline argument) does not find any source-file.
Isn't it open source?

Thanks a lot in advance,
kind regards,
Tom

Generate decimal types?

I'm dealing with money, and have to use a decimal type to avoid "unatural" floating point rounding. See Wikipedia for examples.

I have changed my Swagger config to generate number with decimal format:
c.MapType(() => new Schema { type = "number", format = "decimal" });

The swagger.json now has decimal fields described like this:
"interestRateField":{"format":"decimal","type":"number"}

Autorest still use float fot this field:
public double? InterestRateField

How do I make Autorest use decimal instead of floating point? I can't see that I ever need floating point in my external interfaces, and decimal can by used in all situations if this makes a fix easier.

Error parsing url in method Get with [FromUri] parameter

One of my HttpGet methods has a [FromUri] parameter, a POCO class that contains some properties that serve as optional filter to fetch database info.

When I try "AutoRest.exe -Input v1 -Namespace API -OutputDirectory API", I get the following error:

AutoRest.exe : error: Error parsing URL in method Get. Cannot find a parameter named filters.
At line:1 char:13

  • AutoRest.exe <<<< -Input v1 -Namespace API -OutputDirectory API
    • CategoryInfo : NotSpecified: (error: Error pa... named filters.:String) [], RemoteException
    • FullyQualifiedErrorId : NativeCommandError

Nome do parรขmetro: parameter

The method Get and the parameter class are the following:

[HttpGet]
[Route("/api/calendar")]
public CalendarEvent[] Get([FromUri]GetCalendarEvents filters)
{
    return _dao.Get(filters);
}
public class GetCalendarEvents
{
    public DateTime? Date { get; set; }

    public string Title { get; set; }
}

To access this resource the url will be "http://localhost/api/calendar?filters.date=a&filters.title=b" and swagger-ui do it right.

My swagger spec is:

{
    "swagger": "2.0",
    "info": {
        "version": "v1",
        "title": "API"
    },
    "host": "localhost",
    "schemes": ["http"],
    "paths": {
        "/api/calendar": {
            "get": {
                "tags": ["Calendar"],
                "operationId": "Calendar_Get",
                "consumes": [],
                "produces": ["application/json", "text/json", "application/xml", "text/xml"],
                "parameters": [{
                    "name": "filters.date",
                    "in": "query",
                    "required": false,
                    "type": "string",
                    "format": "date-time"
                },
                {
                    "name": "filters.title",
                    "in": "query",
                    "required": false,
                    "type": "string"
                },
                {
                    "name": "Authorization",
                    "in": "header",
                    "required": true,
                    "type": "string"
                }],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "array",
                            "items": {
                                "$ref": "#/definitions/CalendarEvent"
                            }
                        }
                    }
                },
                "deprecated": false
            }
        }
    },
    "definitions": {
        "GetCalendarEvents": {
            "type": "object",
            "properties": {
                "Date": {
                    "format": "date-time",
                    "type": "string"
                },
                "Title": {
                    "type": "string"
                }
            }
        },
        "CalendarEvent": {
            "type": "object",
            "properties": {
                "Id": {
                    "format": "int32",
                    "type": "integer"
                },
                "Date": {
                    "format": "date-time",
                    "type": "string"
                },
                "Title": {
                    "type": "string"
                }
            }
        }
    }
}

To every method I added a http header 'Authorization' (as seen on swagger spec) to authorization.
It seems to me that AutoRest doesn't support complex class on query.

An alternative solution would be declaring all filters explicitly as parameters like this:

[HttpGet]
[Route("/api/calendar")]
public CalendarEvent[] Get(DateTime? date, string title)
{
    ...
}

But this is out of the question to me as I'll have many filters not just these two.
Is there other way to fix this?

-outputFileName has been removed in latest versions

"-outputFileName" was a parameter that allowed all the entries for a swagger file to be put into a single file. We automate the generation of the swagger json and generation of the code from it. The single file option was optimal for automation for the following reasons:
a) When new model elements or methods were generated, the files remained the same, so a new build would include them with no extra work
b) If new files need to be added, they need to be added to both the Visual Studio project AND source control which is hard/impossible to automate and error prone to do manually

It would be good if this property can be re-enabled.

add support for "examples" in responses object

Including "examples" in a swagger spec results in an error

error: [ Fatal ] Error generating client model: Requested value 'examples' was not found.
Finished generating CSharp code for swagger.json.

Swagger example located here. Definition of example here for use in the response object defined here

Where is the proxy generation code

I'm not finding the code that generates the client classes (i.e. that builds AutoRest.exe). Is this repository just the Microsoft.Rest.ClientRuntime library and samples, or am I missing something?

If this repository doesn't include the code for AutoRest.exe, then the name is quite misleading.

Choco Install - Newtonsoft Dependency missing

Hi,

Love the project, having a play now.

Looks like your missing the Newtonsoft.Json.dll from the Choco package. With the current package you get the following output.

 C:\WINDOWS\system32> choco install autorest
!!ATTENTION!!
The next version of Chocolatey (v0.9.9) will require -y to perform
  behaviors that change state without prompting for confirmation. Start
  using it now in your automated scripts.

  For details on the all new Chocolatey, visit http://bit.ly/new_choco
Chocolatey (v0.9.8.33) is installing 'autorest' and dependencies. By installing you accept the license for 'autorest' an
d each dependency you are installing.

AutoRest v0.9.6
Added C:\ProgramData\chocolatey\bin\AutoRest.exe shim pointed to '..\lib\autorest.0.9.6\tools\autorest.exe'.
Finished installing 'autorest' and dependencies - if errors not shown in console, none detected. Check log for errors if
 unsure.
C:\WINDOWS\system32> autorest
Microsoft (R) AutoRest 0.9.6.0
Copyright (C) Microsoft Corporation. All rights reserved.

Usage: AutoRest.exe -Input <value> -Namespace <value> [-OutputDirectory <value>] [-OutputFileName <value>] [-CodeGenerat
or <value>] [-Modeler <value>] [-ClientName <value>] [-Header <value>] [-AddCredentials <value>]

Parameters:
  -Input: The location of the input specification.
  -Namespace: The namespace to use for generated code.
  -OutputDirectory: The location for generated files. If not specified, uses "Generated" as the default.
  -OutputFileName: If specified, all generated code is written to this file. Otherwise, code is generated into multiple
files in the OutputDirectory.
  -CodeGenerator: The code generator language. If not specified, defaults to CSharp.
  -Modeler: The Modeler to use on the input. If not specified, defaults to Swagger.
  -ClientName: Name to use for the generated client type. By default, uses the value of the 'Title' field from the Swagg
er input.
  -Header: Text to include as a header comment in generated files. Use NONE to suppress the default header.
  -AddCredentials: If true, the generated client includes a ServiceClientCredentials property and constructor parameter.
 Authentication behaviors are implemented by extending the ServiceClientCredentials type.


Examples:
  Generate C# client in MyNamespace from swagger.json input:
  >AutoRest.exe -Namespace MyNamespace -Input swagger.json

  Generate C# client in MyNamespace into client.cs including custom header from swagger.json input:
  >AutoRest.exe -Namespace MyNamespace -OutputFileName client.cs -Header "Copyright Contoso Ltd" -Input swagger.json

  Generate C# client with a credentials property in MyNamespace from swagger.json input:
  >AutoRest.exe -AddCredentials true -Namespace MyNamespace -CodeGenerator CSharp -Modeler Swagger -Input swagger.json


C:\WINDOWS\system32> cd "C:\Users\xxxxxx\Documents\CustomerTemp\autorest\"
C:\Users\xxxxxxx\Documents\CustomerTemp\autorest> ls


    Directory: C:\Users\xxxxxx\Documents\CustomerTemp\autorest


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       25/03/2015     12:12           3663 devinsight.api.json


C:\Users\xxxxx\Documents\CustomerTemp\autorest> autorest -codegenerator CSharp -Modeler Swagger -Input .\devinsight.a
pi.json -Namespace DevInsight
error: Could not load file or assembly 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6ae
ed' or one of its dependencies. The system cannot find the file specified.
Finished generating CSharp code for .\devinsight.api.json.

I grabbed the latest newtonsoft dll from here and placed it in "C:\ProgramData\chocolatey\lib\AutoRest.0.9.6\tools" manually and all seems to work well.

image

image

Discussion: Modeling LRO using swagger

Hi,

Let's say I have one operation called RunWorkflow which returns 202, and it have RequestInfo in the response body. The Location header of the 202 response points to another operation named 'GetRunWorkflowResult', which return 200 and have RunResult in the response body.

Looks like we currently model the LRO like below:

"RunWorkflow": {
            "post": {
                "description": "Runs a workflow.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "RunResult (instead of RequestInfo)"
                        }
                    }
                },
                "x-ms-long-running-operation": true
            }
        },

If my understand it correctly, the responses defined in the RunWorkflowOperation is really for responses of GetRunWorkflowResult. That feels like incorrect from swagger spec's point of view.

Is there any discussion over this topic?

Discussion: JSON string parameter

Hi,

The parameters of our operation looks like below.

 "Workflow": {
    "type": "object",
    "properties": {
        "definition": {
            "$ref": "#/definitions/Object", // this is arbitrary JSON
            "description": "Gets or sets the definition."
        },
    }
}

It has a property called "definition" that is a JSON object representing the definition of a workflow. Instead of having it as a Object/JToken in the data model, we want the data model to be a JSON string like below.

class Workflow {
    public string Definition { get; set; } // This is a JSON string. eg "{ \"foo\": \"bar\"}"
}

We want the JSON string to be converted to JSON object and be embedded in the request as JSON object, and The JSON object in the response will be converted to a JSON string as well.

Is this something that we could do now? Or is this something that we could consider support?

error response codes in swagger json are being treated as non-errors in C# code

If error responses are given in the swagger json, they are not being treated as errors in the C# generated code.

Given the following JSON:

                "responses" : {
                    "201" : {
                        "description" : "Created",
                        "schema" : {
                            "$ref" : "#/definitions/MyItem"
                        }
                    },
                    "404" : {
                        "description" : "If the Actor is not found"
                    },
                    "409" : {
                        "description" : "Conflict - Just because"
                    }
                },

It will produce the following C# code:

            if (!(statusCode == (HttpStatusCode)Enum.Parse(typeof(HttpStatusCode), "Created") || statusCode == (HttpStatusCode)Enum.Parse(typeof(HttpStatusCode), "NotFound") || statusCode == (HttpStatusCode)Enum.Parse(typeof(HttpStatusCode), "Conflict")))
            {
                var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", statusCode));

When we really only want the Created message to be ignored from raising an exception, and everything else should still raise an exception. One solution of course is to not put the failure response codes in the response part of the json, however then it doesn't appear anywhere in the swaggerUI and so other developers can't see what the expected responses are.

Discussion: Internal IServiceOperations

I'm evaluating Autorest against a lightly modified WebApiProxy project.

One of my design goals is to bridge local and remote services via a common interface. In other words I would like 'IMemberService' to point to a concrete instance or over-the-wire-by-client instance by toggling the DI registration.

Having looked at the default CSharp code generator it appears that all of the IServiceOperations are internal classes and they can't be constructed outside of the project housing generated code. Ideally I'd like to inject individual services as required (i.e.: Project A might require 2 services and Project B might require 3 different services and one shared) and construct them at DI configuration.

I'd also like to subclass the IServiceOperations to add a 'business faรงade', for example, shared service 'IUserPreferenceService' might 'get' and 'set' a generic 'UserPreferenceModel ', but the the service would benefit from per-project convenience overloads, such as SetCountry(string country) and string GetCountry().

Can you make the default IServiceOperations a little more decoupled and public?

Kind regards

Auto-generated proxy doesn't work with endpoints which return actual file content.

There is an issue with autogenerated proxy - if WebAPI endpoint returns file content something like this:

public async Task<HttpResponseMessage> DownloadFile(string id)
{
...
    var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(fileArray) };
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = itemToDownload.Name };
}

And I want to call method on proxy with WithOperationResponseAsync suffix which returns Task<HttpOperationResponse> - assuming that string will be passed as is and not interpret in any way. AutoGenerated proxy reads data as string and tries to deserialize string as json:

            string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);

...
            // Deserialize Response
            if (statusCode == HttpStatusCode.OK)
            {
                string resultModel = default(string);
                JToken responseDoc = null;
                if (string.IsNullOrEmpty(responseContent) == false)
                {
                    responseDoc = JToken.Parse(responseContent);
                }
                if (responseDoc != null)
                {
                    resultModel = responseDoc.ToString(Newtonsoft.Json.Formatting.Indented);
                }
                result.Body = resultModel;
            }

Looks like a bug to me.
Also it might be good option to support access to raw HttpClient response

Little tiny style issues

in data model
        /// <summary>
        /// Gets or sets the state. Possible values for this property include:
        /// 'NotSpecified', 'Enabled', 'Disabled', 'Deleted', 'Suspended' (missing full stop)
        /// </summary>
        [JsonProperty(PropertyName = "properties.state")]
        public WorkflowState? State { get; set; }
in client
        /// <summary>
        /// Management credentials for Azure.  (should begin with 'The')
        /// </summary>
        ServiceClientCredentials Credentials { get; }
in operation extensions
            /// <summary>
            /// Gets a list of workflow runs.
            /// </summary>
            /// <param name='operations'>
            /// The operations group for this extension method.
            /// </param>
            /// <param name='nextPageLink'>
            /// NextLink from the previous successful call to List operation. (should begin with 'The')
            /// </param>
            /// <param name='cancellationToken'>
            /// Cancellation token. (should begin with 'The')
            /// </param>
            public static async Task<Page<WorkflowRun>> ListNextAsync( this IWorkflowRunsOperations operations, string nextPageLink, CancellationToken cancellationToken = default(CancellationToken))
            {
                AzureOperationResponse<Page<WorkflowRun>> result = await operations.ListNextWithHttpMessagesAsync(nextPageLink, null, cancellationToken).ConfigureAwait(false);
                return result.Body;
            }
in data model. where can we put description in swagger? I tried adding description for definition, but looks like no effect.
    /// <summary> (empty summary)
    /// </summary>
    public partial class WorkflowAccessKey : SubResource
in operations
    /// <summary> (empty summary)
    /// </summary>
    public partial interface IWorkflowAccessKeysOperations

Global parameters like subscriptionId and apiVersion is defined in the client implementation but not in client interface

    public partial interface ILogicManagementClient
    {
        /// <summary>
        /// The base URI of the service.
        /// </summary>
        Uri BaseUri { get; set; }

        IWorkflowsOperations Workflows { get; }

        IWorkflowVersionsOperations WorkflowVersions { get; }

        IWorkflowAccessKeysOperations WorkflowAccessKeys { get; }

        IWorkflowTriggersOperations WorkflowTriggers { get; }

        IWorkflowTriggerHistoriesOperations WorkflowTriggerHistories { get; }

        IWorkflowRunsOperations WorkflowRuns { get; }

        IWorkflowRunActionsOperations WorkflowRunActions { get; }

        }

    public partial class LogicManagementClient : ServiceClient<LogicManagementClient>, ILogicManagementClient, IAzureClient
    {
        ...

        /// <summary>
        /// The subscription id.
        /// </summary>
        public string SubscriptionId { get; set; }

        /// <summary>
        /// The API version.
        /// </summary>
        public string ApiVersion { get; private set; }

        /// <summary>
        /// The retry timeout for Long Running Operations.
        /// </summary>
        public int? LongRunningOperationRetryTimeout { get; set; }

        public virtual IWorkflowsOperations Workflows { get; private set; }

        public virtual IWorkflowVersionsOperations WorkflowVersions { get; private set; }

        public virtual IWorkflowAccessKeysOperations WorkflowAccessKeys { get; private set; }

        public virtual IWorkflowTriggersOperations WorkflowTriggers { get; private set; }

        public virtual IWorkflowTriggerHistoriesOperations WorkflowTriggerHistories { get; private set; }

        public virtual IWorkflowRunsOperations WorkflowRuns { get; private set; }

        public virtual IWorkflowRunActionsOperations WorkflowRunActions { get; private set; }

        ...
    }

It would be good to have the global parameters in ILogicManagementClient as well.

Issue with generated header message

Hi,

I'm using below command to generate code.

AutoRest.exe -Input my.json -Namespace MyNamespace -Header MICROSOFT_APACHE -CodeGenerator Azure.CSharp -AddCredentials

The generated header (pasted at the end) contains message like 'Code generated by Microsoft (R) AutoRest Code Generator {0} ...'.

  • Can I disable the generation of this message?
  • The message contains {0} which I assume should be replaced by some thing.
/// 
/// Copyright (c) Microsoft and contributors.  All rights reserved.
/// 
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
/// http://www.apache.org/licenses/LICENSE-2.0
/// 
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// 
/// See the License for the specific language governing permissions and
/// limitations under the License.
/// Code generated by Microsoft (R) AutoRest Code Generator {0}
/// Changes may cause incorrect behavior and will be lost if the code is
/// regenerated.

Exception when serializing property of type object using JObject.Parse.

I have a web API whose return type is DTO1. DTO1 has a property P1 of type object

I have auto generated webapi client using AutoRest.0.9.7

When i try to make a request to webAPi using auto generated client, it gives exception.

Exception when serializing property P1 using JObject.Parse.

The Value of P1 at point when exception was thrown was "value1"...

I believe there is not way to convert string value ("value1") using JObject.Parse.

JObject.Parse always expects the string passed to be a json string.

On contrary when i use JsonConter.Serialize , the serialization works fine..

Can I use enumerations?

Support Autorest enum generation?
And if "yes" how should I describe swagger spec for generate enumeration?

Use -NoProfile in powershell.exe invocations

Hello, a customized profile.ps1 can interfere with the build steps invoking PowerShell scripts. Adding the -NoProfile option when calling powershell.exe can prevent that. I modified:

  • tools/AutoRest.Settings.targets
  • tools/RegenerateExpectedClasses.ps1
  • tools/Sync-NuspecDependencies.ps1
    with good results on the master branch although I haven't tried it out on the dev branch yet.

AutoRest failed to generate code

I got a swagger like below (at the end). AutoRest works fine until recently it stopped generating code with below error.

error: [FATAL] Error generating client model: Value cannot be null.
Parameter name: key

The error message wasn't helpful but after debugging the issue lays in in below code:

//  AutoRest\Modelers\Swagger\ParameterBuilder.cs
public Parameter Build()
        {
            string parameterName = _swaggerParameter.Name;
            SwaggerParameter unwrappedParameter = _swaggerParameter;

            if (_swaggerParameter.Reference != null)
            {
                unwrappedParameter = Modeler.Unwrap(_swaggerParameter);
            }

            if (unwrappedParameter.Schema != null && unwrappedParameter.Schema.Reference != null)
            {
                parameterName = unwrappedParameter.Schema.Reference.StripDefinitionPath();
            }

            // HERE the parameterName is null. It should not be null.
            IType parameterType = BuildServiceType(parameterName);
My parameter in swagger:
            "workflow": {
                "name": "parameters",
                "description": "The parameters.",
                "in": "body",
                "required": true,
                "schema": {
                    "$ref": "#/definitions/Workflow"
                }
            },

My definitions in swagger:

"Workflow": {
            "type": "object",
            "properties": {
                "properties": {
                    "$ref": "#/definitions/WorkflowProperties",
                    "description": "Gets or sets the workflow properties."
                }
            },
            "allOf": [
                {
                    "$ref": "Resource"
                }
            ]
        },
        "WorkflowProperties": {
            "type": "object",
            "properties": {
                "createdTime": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Gets or sets the created time."
                },
                "changedTime": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Gets or sets the changed time."
                },
                "state": {
                    "$ref": "#/definitions/WorkflowState",
                    "description": "Gets or sets the state."
                },
                "version": {
                    "type": "string",
                    "description": "Gets or sets the version."
                },
                "accessEndpoint": {
                    "type": "string",
                    "description": "Gets or sets the access endpoint."
                },
                "sku": {
                    "$ref": "#/definitions/Sku",
                    "description": "Gets or sets the sku."
                },
                "definitionLink": {
                    "$ref": "#/definitions/ContentLink",
                    "description": "Gets or sets the link to definition."
                },
                "definition": {
                    "$ref": "#/definitions/Object",
                    "description": "Gets or sets the definition."
                },
                "parametersLink": {
                    "$ref": "#/definitions/ContentLink",
                    "description": "Gets or sets the link to parameters."
                },
                "parameters": {
                    "type": "object",
                    "additionalProperties": {
                        "$ref": "#/definitions/WorkflowParameter"
                    },
                    "description": "Gets or sets the parameters."
                }
            }
        },

Discussion: 'properties' property is embbeded in the request even if user didn't specify any value

I'm trying to call PATCH on a resource like below.

                // Workflow is derived from Resource
                workflow = new Workflow()
                    {
                        Tags = new Dictionary<string, string>()
                    };
                workflow.Tags.Add("abc", "def");
                workflow = client.Workflows.Update(this.resourceGroupName, workflowName, workflow);

The actual request body is like below, which causes an error because 'properties' was set to an empty object.

{
  "tags": {
    "abc": "def"
  },
  "properties": {}
}

Expected request body is like below:

{
  "tags": {
    "abc": "def"
  }
}

Is it possible to have generated SDK not emitting 'properties' in this case? Bottom line, I could define the same model again with a different name that is not derived from Resource in order to workaround the problem caused by flattening the properties.

Fails on YAML comments

I'm just getting started with Swagger and AutoRest, but it appears that your tool doesn't support comments in the Swagger YAML specification.

The swagger spec I'm using is here, which starts with some comments:

# this is an example of the Visual Studio Online Git AP
# as a demonstration of an API spec in YAML
swagger: '2.0'

This works in the Swagger Editor, but fails when using AutoRest:

> .\AutoRest.0.9.7\tools\AutoRest.exe -Input .\vso-git.yaml -Namespace 'VSOGit.Client' -OutputDirectory 'Client' 
error: [FATAL] Error parsing swagger file. Unexpected character encountered while parsing value: #. Path '', line 0, position 0.
Finished generating CSharp code for .\vso-git.yaml.

ServiceClientCredentials.InitializeServiceClient<T> not called on client constructor

We have a ServiceClientCredentials implementation that logins to our service on client creation, then stores to authentication credentials for subsequent requests. This worked fine with the old version

public class CustomLoginCredentials : ServiceClientCredentials {
  private string AuthenticationToken { get; set; }
  public override void InitializeServiceClient<T>(ServiceClient<T> client) {
    // make login request.  save authentication token in AuthenticationToken
  }

 public override Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
   // place AuthenticationToken in request header
 }
}

So then declaring our client
var client = new ClientAPI(new Uri("url"), new CustomLoginCredentials());

The InitializeMethod would get called and then all requests would be properly authenticated.

This does work any more in the new version. Please let me know if this is a bug (I could see into fixing it myself) or some new intended behavior.

example element in swagger schema definition cannot be object type

When I try to parse a swagger document which contains an example property under schema definition. It gives following error:
error: [FATAL] Error parsing swagger file. Error reading string. Unexpected token: StartObject. Path 'example', line 11, position 15.

It seems that the tool can only parse example property with string type. However, in swagger 2.0 spec, it defines example as any type. Here is an example model from the spec:

{
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
},
"required": [
"name"
],
"example": {
"name": "Puma",
"id": 1
}
}

Feature Request: Add option to suppress synchronous method generation

Would it be possible to add a generation option that suppresses synchronous method generation (or maybe better, specify async, sync or both)?

I only use async methods and the synchronous methods add clutter and open the door for future programmers on my project to fall into the trap of not using async for everything.

I can't think of a good name but maybe something like this

-Synchronicity AsyncOnly|SyncOnly|Both

P.S. Recently discovered autorest and it looks like it could be a huge help for me

Problem with AutoRest.exe generated deserializer

The auto generated deserializer seems to have a problem with deserializing dictionary types.

The swagger definition has a property of:

myDictionary": { "type":"object", "additionalProperties":{"type":"string"} }

AutoRest produces an correct member property (public IDictionary<string, string> MyDictionary), but the serializer for that property is as the following:

JToken stringDictionary = ((JToken)inputObject["string"]); 
if (stringDictionary != null && stringDictionary.Type != JTokenType.Null) 
{ 
  foreach (JProperty property in stringDictionary) 
  { 
    this.MyDictionary.Add(((string)property.Name), ((string)property.Value)); 
  }
}

It seems to work as expected if i change the deserializer to the following:

JToken stringDictionary = ((JToken)inputObject["myDictionary"]); 
if (stringDictionary != null && stringDictionary.Type != JTokenType.Null) 
{ 
  foreach (JProperty property in stringDictionary) 
  { 
    this.MyDictionary.Add(((string)property.Name), ((string)property.Value)); 
  } 
}

Create a nix packaged executable

I'd like to have a single package to use from the command line. For example, rather than mono AutoRest.exe [options], I'd rather have autorest [options].

This looks to be pretty easy to do via: mkbundle

Ambiguous reference for entities on namespace System

I have a class Action.

AutoRest generates a class Action on namespace MyNamespace.Models and
ActionOperations, ActionOperationsExtensions and IActionOperations on namespace MyNamespace.

Methods on both ActionOperations, ActionOperationsExtensions and IActionOperations reference Action and have "using System" which causes an ambigous reference between 'System.Action' and 'MyNamespace.Models.Action'.

I see four solutions:

  • Detect conflit and rename the entity as it already does for ActionOperations.

warning: Client operation with name 'Action' was renamed to 'ActionOperations' because it conflicts with following entities: Action (already used in schema definition)
Please consider changing your swagger specification to avoid naming conflicts.

  • Put all classes and interfaces related to the entity on the same namespace.

For example, put both Action, ActionOperations, ActionOperationsExtensions and IActionOperations on MyNamespace.

  • Add using statement Entity = MyNamespace.Models.Entity on each class and interface generated.

For example, adding "using Action = MyNamespace.Models.Action".

  • Use the entity's full description (MyNamespace.Models.Entity) every time.

Microsoft.Rest.HttpOperationResponse<System.Collections.Generic.IList<MyNamespace.Models.Action>> result = await operations.GetWithOperationResponseAsync(authorization, cancellationToken).ConfigureAwait(false);

autorest ignores e.g. HttpStatusCode.Created

Hello

I just started with Swagger and I think there are more valid Response Codes than only HttpStatusCode.OK.

For example, this code throws an Exception - even if HttpStatusCode.Created:

        if (statusCode != HttpStatusCode.OK)
        {
            HttpOperationException<object> ex = new HttpOperationException<object>();
            ex.Request = httpRequest;
            ex.Response = httpResponse;
            ex.Body = null;
            if (shouldTrace)
            {
                ServiceClientTracing.Error(invocationId, ex);
            }
            throw ex;
        }

Therefore I think it woule be useful if one can pass valid HttpStatusCodes, or if such functions just return the StatusCode and allow the User to decide if something is an exeception :-)

Thanks for your very usefule work!
kind regards,
Tom

Deserializing null

I have a REST service with a GET method returning a complex type. If I return null from that service, then the generated C# client (from AutoRest) will return a new empty object (of my return type) instead of null.

The code in the generated client looks like this:

// Deserialize Response
if (statusCode == HttpStatusCode.OK)
{
    AttributeDto resultModel = new AttributeDto();
    JToken responseDoc = null;
    if (string.IsNullOrEmpty(responseContent) == false)
    {
        responseDoc = JToken.Parse(responseContent);
    }
    if (responseDoc != null)
    {
        resultModel.DeserializeJson(responseDoc);
    }
    result.Body = resultModel;
}

Is there a reason for always returning a new empty object instead of null?
Also: Will you release the proxy generation code here on GitHub anytime soon? I think AutoRest works great, but I would like to be able to return null.

Add Travis Support

It would be nice to have this building on travis now that there is mono support.

Model was missing from generated code even though it is used directly

Hi all,

I have below swagger.

operation:

"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/...": {
            "post": {
                ...
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/WorkflowAccessKeyProperties"
                        }
                    }
                }
            }
        },

definitions:
        "Resource": {
            "properties": {
                "id": {
                    "type": "string",
                    "description": "Gets or sets the resource id."
                },
                ...
            },
            "x-ms-external": true
        },
        "WorkflowAccessKey": {
            "type": "object",
            "properties": {
                "properties": {
                    "$ref": "#/definitions/WorkflowAccessKeyProperties",
                    "description": "Gets or sets the workflow access key properties."
                }
            },
            "allOf": [
                {
                    "$ref": "Resource"
                }
            ]
        },
        "WorkflowAccessKeyProperties": {
            "type": "object",
            "properties": {
                ...
            }
        }

The model WorkflowAccessKeyProperties was missing from generated code, even though it is used by the operation.

Sentence styling for descriptions

Hi,

Below is generated code. For consistency the description below for parameters should be changed to:

        /// <param name='customHeaders'>
        /// The headers that will be added to request.
        /// </param>
        /// <param name='cancellationToken'>
        /// The cancellation token.
        /// </param>

Actual:

Task<AzureOperationResponse<WorkflowListResponse>> ListByResourceGroupWithHttpMessagesAsync(string resourceGroupName, int? top = default(int?), string filter = default(string), Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken));
        /// <summary>
        /// Gets a workflow.
        /// </summary>
        /// <param name='resourceGroupName'>
        /// The resource group name.
        /// </param>
        /// <param name='workflowName'>
        /// The workflow name.
        /// </param>
        /// <param name='customHeaders'>
        /// Headers that will be added to request.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        Task<AzureOperationResponse<Workflow>> GetWithHttpMessagesAsync(string resourceGroupName, string workflowName, Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken));

Also, description should end with a full stop in below:

    /// <summary>
    /// Defines values for SkuName (missing full stop)
    /// </summary>
    [JsonConverter(typeof(StringEnumConverter))]
    public enum SkuName
    {
        [EnumMember(Value = "Free")]
        Free,
        [EnumMember(Value = "Shared")]
        Shared,
        [EnumMember(Value = "Basic")]
        Basic,
        [EnumMember(Value = "Standard")]
        Standard,
        [EnumMember(Value = "Premium")]
        Premium
    }

        /// <summary>
        /// Gets or sets the name. Possible values for this property include:
        /// 'Free', 'Shared', 'Basic', 'Standard', 'Premium' (missing full stop)
        /// </summary>
        [JsonProperty(PropertyName = "name")]
        public SkuName? Name { get; set; }

PropertyName has "properties." as prefix

This is related to #195 . Now the model is generated, however with the wrong propertyName. It should not have 'properties.' as prefix.

    /// <summary>
    /// </summary>
    public partial class WorkflowAccessKeyProperties
    {
        /// <summary>
        /// Gets or sets the not-before time.
        /// </summary>
        [JsonProperty(PropertyName = "properties.notBefore")]
        public DateTime? NotBefore { get; set; }

        /// <summary>
        /// Gets or sets the not-after time.
        /// </summary>
        [JsonProperty(PropertyName = "properties.notAfter")]
        public DateTime? NotAfter { get; set; }

        /// <summary>
        /// Gets the primary secret key.
        /// </summary>
        [JsonProperty(PropertyName = "properties.primarySecretKey")]
        public string PrimarySecretKey { get; private set; }

        /// <summary>
        /// Gets the secondary secret key.
        /// </summary>
        [JsonProperty(PropertyName = "properties.secondarySecretKey")]
        public string SecondarySecretKey { get; private set; }

    }

Build error for the generated file header

I got below error (we treat warning as error) for the generated code.

1> WorkflowTriggersOperationsExtensions.cs(1,1,1,2): warning CS1587: XML comment is not placed on a valid language element

It's complaining about header on top of the file below.

/// 
/// Copyright (c) Microsoft and contributors.  All rights reserved.
/// 
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
/// http://www.apache.org/licenses/LICENSE-2.0
/// 
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// 
/// See the License for the specific language governing permissions and
/// limitations under the License.
/// Code generated by Microsoft (R) AutoRest Code Generator {0}
/// Changes may cause incorrect behavior and will be lost if the code is
/// regenerated.
namespace Microsoft.Azure.Management.Logic
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Rest;
    using System.Linq.Expressions;
    using Microsoft.Azure;
    using Models;

Looking at the MDSN for the error at https://msdn.microsoft.com/en-us/library/d3x6ez1z(v=vs.90).aspx. Looks like we could:

  1. Use double slashes instead of triple slashes, because the comment doesn't contain any tags.
  2. Have an empty line between the comment and namespace.

Request: adding ResourceReference into Azure ClientRuntime dll

Hi all,

I have below definition which represent a reference to an azure resource. Looks like it's pretty common. Can we consider adding below data model to the Azure ClientRuntime dll?

    "ResourceReference": {
        "type": "object",
        "properties": {
            "id": {
                "type": "string",
                "description": "Gets or sets the resource id."
            },
            "name": {
                "type": "string",
                "readOnly": true,
                "description": "Gets the resource name."
            },
            "type": {
                "type": "string",
                "readOnly": true,
                "description": "Gets the resource type."
            }
        }
    },

When swagger.json contains "Client" entity, generated C# code doesn't compile

Hey

When I generate client using autorest.exe and swagger.json contains "Client" entity, generated C# code doesn't compile since name of the generated class is Client and each class contains Client property and both can't have the same name. Also where I can find source code of the acctual autorest.exe since I couldn't locate the code in repository?

Thanks a lot

Question - lifetime management of ServiceClient?

How should the lifetime of the ServiceClient be managed in an Azure server app like WebJobs or ASP.NET Web API site? In essence the ServiceClient is a wrapper around HttpClient. Disposing the HttpClient results in unexpected behaviour (random connection issues). Articles like this http://chimera.labs.oreilly.com/books/1234000001708/ch14.html#_httpclient_class suggest using a single HttpClient per application (AppPool?), so effectively one per base URI. You would assume that the ServiceClient would map to a single instance as well in that case for best network efficiency.
Is there any guideline how the typed ServiceClient should be used in a server application doing REST calls?

Wrong package version was displayed in output of autorest.exe

When I run autorest, below is the output:

The Microsoft.Rest.ClientRuntime.Azure.1.0.12 nuget package is required to compile the generated code.
Finished generating Azure.CSharp code for logic.json.

However, the generated code will not work following that output. It should be 1.0.13.

In additionl, it would be cool if the output contains the full list of packages that is needed in order to compile the generated code, which includes some system dll and ClientRuntime 1.1.0, etc.

Required properties

C# generator creates all primitive type properties as Nullable<T>. If the property is declared as required in swagger.json should we generate property of type T instead of Nullable<T>?

The required flag is already captured and PrimaryType could be easily extended to support nullability explicitly - SwaggerObject.ToType() method could just use already present IsReguired property.

A config option can be added to turn this behaviour on/off if backwards compatibility is required.

I'm happy to create a PR - just wondering if there are any side-effects I'm not aware of.

Derived class should use 'override' for Validate() method

I have a data model named Workflow derived from Resource. swagger below:

        "Workflow": {
            "type": "object",
            "properties": {
                "properties": {
                    "$ref": "#/definitions/WorkflowProperties",
                    "description": "Gets or sets the workflow properties."
                }
            },
            "allOf": [
                {
                    "$ref": "Resource"
                }
            ]
        },

Generated code looks like below:

    public partial class Workflow : Resource
    {
        ...

        /// <summary>
        /// Validate the object. Throws ArgumentException or ArgumentNullException if validation fails.
        /// </summary>
        public virtual void Validate()
        {
            ...
        }
    }
}

I got below error when compiling:

1>Generated\Models\Workflow.cs(95,29,95,37): warning CS0114: 'Microsoft.Azure.Management.Logic.Models.Workflow.Validate()' hides inherited member 'Microsoft.Azure.Resource.Validate()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.

No null check on Credentials object in Generated CSharp code

With this new version (I upgraded from 0.9.6), it looks like there is no null check on the Credentials object in the generated code

...
// Set Credentials
cancellationToken.ThrowIfCancellationRequested();
await this.Client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);

// Serialize Request  
...

// Send Request

We are generating the code with the -AddCredentials flags but not every request will have the credentials set, particularly the login request will not. Right now I have to set it to a dummy credentials object just to work around this issue. Also since the Credentials property of the api is settable to null, it makes no sense to assume the Credentials will never be null

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.