microsoft / typespec

https://typespec.io/
MIT License
4.46k stars 209 forks source link

[feature] implement client parameter apiversion #4206

Closed chunyu3 closed 2 weeks ago

chunyu3 commented 2 months ago

When the service is versioned, the client will has apiVersion field. Each operation which has apiVersion parameter should use the client apiVersion parameter directly and the operation signature should not include the apiVersion parameter.

chunyu3 commented 2 months ago

typespec:

@versioned(Versions)
@service({
    title: "hello world"
})
@doc("This is a sample typespec project.")
@server(
    "{firstTestTypeSpecUrl}",
    "Endpoint Service",
    {
        firstTestTypeSpecUrl: string,
    }
)
@useAuth(
    OAuth2Auth<[AuthFlow]> | ApiKeyAuth<ApiKeyLocation.header, "x-ms-api-key">
)
namespace FirstTestTypeSpec;

@doc("The auth flow model")
model AuthFlow {
    type: OAuth2FlowType.clientCredentials;
    tokenUrl: "https://api.example.com/oauth2/token";
    refreshUrl: "https://api.example.com/oauth2/refresh";
    scopes: ["https://api.example.com/.default"];
}

enum Versions {
    @useDependency(Azure.Core.Versions.v1_0_Preview_1)
    "2022-05-15-preview"
  }
@route("/helloWithApiVersion")
    @doc("Return hi again")
    @get
    @convenientAPI(true)
    op hello(
        @header p1: string,
        @query apiVersion: string
    ):void;

    @route("/helloWithOutApiVersion")
    @doc("Return hi again")
    @get
    @convenientAPI(true)
    op helloAgain(
        @header p1: string,
    ):void;

Generated Code: THe apiVersion will be the Client parameter

public partial class FirstTestTypeSpecClient
    {
        private const string AuthorizationHeader = "x-ms-api-key";
        private readonly AzureKeyCredential _keyCredential;
        private static readonly string[] AuthorizationScopes = new string[] { "https://api.example.com/.default" };
        private readonly TokenCredential _tokenCredential;
        private readonly HttpPipeline _pipeline;
        private readonly Uri _endpoint;
        private readonly string _apiVersion;
      ......
}

The operation which has apiVersion parameter should use the client apiVersion parameter directly and the operation signature should not include the apiVersion parameter.

public virtual async Task<Response> HelloAsync(string p1, RequestContext context = null)
{

}
 internal HttpMessage CreateHelloRequest(string p1, RequestContext context)
        {
            var message = _pipeline.CreateMessage(context, ResponseClassifier204);
            var request = message.Request;
            request.Method = RequestMethod.Get;
            var uri = new RawRequestUriBuilder();
            uri.Reset(_endpoint);
            uri.AppendPath("/helloWithApiVersion", false);
            uri.AppendQuery("apiVersion", _apiVersion, true);
            request.Uri = uri;
            request.Headers.Add("p1", p1);
            return message;
        }