Azure / autorest.java

Extension for AutoRest (https://github.com/Azure/autorest) that generates Java code
MIT License
32 stars 80 forks source link

tsp, propagate usage/access to children, only for discriminated model #2751

Closed weidongxu-microsoft closed 1 month ago

weidongxu-microsoft commented 1 month ago

Sync usage/access behavior to current TCGC -- sub type of normal "extends" won't get access/usage from its parent.

Reason is that healthinsights is to release GA. This change affect them. See https://github.com/Azure/azure-sdk-for-java/pull/40125/files

local test tsp, to be merged into internal.tsp in future PR

import "@typespec/rest";
import "@typespec/versioning";
import "@azure-tools/typespec-azure-core";
import "@azure-tools/typespec-client-generator-core";

using TypeSpec.Http;
using Azure.Core;
using Azure.ClientGenerator.Core;

@service({
  title: "Internal",
})
namespace Cadl.Internal;

// ApiRequest and RequestInner will be generated
@access(Access.public, "client")
model ApiRequest {
  property: string;
  resource?: Resource;
}

// Response will be generated as output-only
@access(Access.public)
model ApiResponse {
  name: string;
  observation?: Observation;
}

// intput+output
model Resource {
  name: string;
  prop0?: string;
}

// output
@discriminator("kind")
model DomainResource extends Resource {
  kind: string;
  prop1?: string;
}

// output
model Observation extends DomainResource {
  kind: "Observation";
  prop2?: string;
}

// not public
model ObservationSub extends Observation {
  prop3?: string;
}

@route("/internal")
interface InternalOp {
  // test ApiRequest with Access.public
  @access(Access.public, "python")
  @access(Access.internal, "client")
  @post
  postInternal(...ApiRequest): void;

  // test ApiResponse with Access.public
  @get
  @access(Access.internal, "java")
  getInternal(): ApiResponse;
}

PS: It does not handle below case (nor does TCGC -- checked with Chenjie)

@discriminator("kind")
model DomainResource {
  kind: string;
  prop1?: string;
}

model SubType extends DomainResource {
  kind: "a" | "b";
}

model SubSubType extends SubType {
  kind: "a";
}
haolingdong-msft commented 1 month ago

Resource is input + output, why is DomainResource output only?

// intput+output
model Resource {
  name: string;
  prop0?: string;
}

// output
@discriminator("kind")
model DomainResource extends Resource {
  kind: string;
  prop1?: string;
}
weidongxu-microsoft commented 1 month ago

Resource is not a discriminated model.

For response, service cannot send DomainResource if op response body is Resource. (no discriminator means SDK won't serialize to DomainResource)

For request, service likely cannot receive DomainResource if op request body is Resource. (DomainResource likely have more property than Resource, which is expected to be rejected by service, if it expect body as Resource)

So, basically, DomainResource and Resource is not related in REST API (even SDK model them as subclass -- it can choose not to model this way). In case only Resource is used in operation, DomainResource could be not generated at all.

haolingdong-msft commented 1 month ago

ok, I see.