Skip to content

Commit

Permalink
tsp, spread implicit request body (#2821)
Browse files Browse the repository at this point in the history
  • Loading branch information
weidongxu-microsoft authored Jul 10, 2024
1 parent aa25c93 commit a0e9fe7
Show file tree
Hide file tree
Showing 26 changed files with 677 additions and 730 deletions.
8 changes: 8 additions & 0 deletions typespec-extension/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Release History

## 0.18.0 (2024-07-10)

Compatible with compiler 0.57.

### Breaking Changes

- Request body without `@body` or `@bodyRoot`: the properties of the request body is flattened into method signature.

## 0.17.1 (2024-07-03)

Compatible with compiler 0.57.
Expand Down
881 changes: 306 additions & 575 deletions typespec-extension/package-lock.json

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions typespec-extension/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@azure-tools/typespec-java",
"version": "0.17.1",
"version": "0.18.0",
"description": "TypeSpec library for emitting Java client from the TypeSpec REST protocol binding",
"keywords": [
"TypeSpec"
Expand Down Expand Up @@ -49,7 +49,7 @@
"@azure-tools/typespec-azure-resource-manager": ">=0.43.0 <1.0.0",
"@azure-tools/typespec-autorest": ">=0.43.0 <1.0.0",
"@azure-tools/typespec-azure-rulesets": ">=0.43.0 <1.0.0",
"@azure-tools/typespec-client-generator-core": ">=0.43.1 <1.0.0",
"@azure-tools/typespec-client-generator-core": ">=0.43.2 <1.0.0",
"@typespec/compiler": ">=0.57.0 <1.0.0",
"@typespec/http": ">=0.57.0 <1.0.0",
"@typespec/openapi": ">=0.57.0 <1.0.0",
Expand All @@ -67,25 +67,25 @@
"@azure-tools/typespec-azure-resource-manager": "0.43.0",
"@azure-tools/typespec-autorest": "0.43.0",
"@azure-tools/typespec-azure-rulesets": "0.43.0",
"@azure-tools/typespec-client-generator-core": "0.43.1",
"@azure-tools/typespec-client-generator-core": "0.43.2",
"@types/js-yaml": "~4.0.9",
"@types/lodash": "~4.17.1",
"@types/mocha": "~10.0.6",
"@types/node": "~20.12.10",
"@typescript-eslint/eslint-plugin": "~7.8.0",
"@typescript-eslint/parser": "~7.8.0",
"@types/lodash": "~4.17.6",
"@types/mocha": "~10.0.7",
"@types/node": "~20.14.10",
"@typescript-eslint/eslint-plugin": "~7.16.0",
"@typescript-eslint/parser": "~7.16.0",
"@typespec/compiler": "0.57.0",
"@typespec/http": "0.57.0",
"@typespec/openapi": "0.57.0",
"@typespec/rest": "0.57.0",
"@typespec/versioning": "0.57.0",
"@typespec/xml": "0.57.0",
"c8": "~9.1.0",
"c8": "~10.1.2",
"eslint": "~8.57.0",
"eslint-plugin-deprecation": "~2.0.0",
"mocha": "~10.4.0",
"prettier": "~3.2.5",
"rimraf": "~5.0.5",
"typescript": "~5.4.5"
"eslint-plugin-deprecation": "~3.0.0",
"mocha": "~10.6.0",
"prettier": "~3.3.2",
"rimraf": "~6.0.0",
"typescript": "~5.5.3"
}
}
12 changes: 8 additions & 4 deletions typespec-extension/src/code-model-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,7 @@ export class CodeModelBuilder {
this.processParameterBody(codeModelOperation, op, op.parameters.body.property);
}
} else if (op.parameters.body.type) {
let bodyType = this.getEffectiveSchemaType(op.parameters.body.type);
let bodyType = op.parameters.body.type;

if (bodyType.kind === "Model") {
// try use resource type as round-trip model
Expand Down Expand Up @@ -1345,7 +1345,11 @@ export class CodeModelBuilder {
schema = this.processSchemaFromSdkType(sdkType, body.name);
}

const isAnonymousModel = sdkType.kind === "model" && sdkType.isGeneratedName === true;
// Explicit body parameter @body or @bodyRoot would result to body.kind === "ModelProperty"
// Implicit body parameter would result to body.kind === "Model"
// see https://typespec.io/docs/libraries/http/cheat-sheet#data-types
const bodyParameterFlatten = sdkType.kind === "model" && body.kind === "Model" && !this.isArm();

const parameterName = body.kind === "Model" ? (sdkType.kind === "model" ? sdkType.name : "") : this.getName(body);
const parameter = new Parameter(parameterName, this.getDoc(body), schema, {
summary: this.getSummary(body),
Expand All @@ -1371,8 +1375,8 @@ export class CodeModelBuilder {
this.trackSchemaUsage(schema, { serializationFormats: [KnownMediaType.Multipart] });
}

if (schema instanceof ObjectSchema && isAnonymousModel) {
// anonymous model
if (schema instanceof ObjectSchema && bodyParameterFlatten) {
// flatten body parameter

// name the schema for documentation
schema.language.default.name = pascalCase(op.language.default.name) + "Request";
Expand Down
8 changes: 4 additions & 4 deletions typespec-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
},
"dependencies": {
"@azure-tools/cadl-ranch-specs": "0.34.3",
"@azure-tools/typespec-java": "file:/../typespec-extension/azure-tools-typespec-java-0.17.1.tgz"
"@azure-tools/typespec-java": "file:/../typespec-extension/azure-tools-typespec-java-0.18.0.tgz"
},
"devDependencies": {
"@typespec/prettier-plugin-typespec": "~0.57.0",
"prettier-plugin-organize-imports": "3.2.4",
"prettier": "~3.2.5"
"prettier-plugin-organize-imports": "4.0.0",
"prettier": "~3.3.2"
},
"overrides": {
"@typespec/compiler": ">=0.57.0 <1.0.0",
Expand All @@ -25,7 +25,7 @@
"@typespec/openapi": ">=0.57.0 <1.0.0",
"@typespec/xml": ">=0.57.0 <1.0.0",
"@azure-tools/typespec-azure-core": ">=0.43.0 <1.0.0",
"@azure-tools/typespec-client-generator-core": ">=0.43.1 <1.0.0",
"@azure-tools/typespec-client-generator-core": "0.43.2",
"@azure-tools/typespec-azure-resource-manager": ">=0.43.0 <1.0.0",
"@azure-tools/typespec-autorest": ">=0.43.0 <1.0.0"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import com.azure.core.http.rest.Response;
import com.azure.core.util.BinaryData;
import com.azure.core.util.FluxUtil;
import com.client.naming.implementation.ModelsImpl;
import com.client.naming.implementation.ClientModelsImpl;
import com.client.naming.models.ClientModel;
import com.client.naming.models.JavaModel;
import reactor.core.publisher.Mono;
Expand All @@ -25,17 +25,17 @@
* Initializes a new instance of the asynchronous NamingClient type.
*/
@ServiceClient(builder = NamingClientBuilder.class, isAsync = true)
public final class ModelAsyncClient {
public final class ClientModelAsyncClient {
@Generated
private final ModelsImpl serviceClient;
private final ClientModelsImpl serviceClient;

/**
* Initializes an instance of ModelAsyncClient class.
* Initializes an instance of ClientModelAsyncClient class.
*
* @param serviceClient the service client implementation.
*/
@Generated
ModelAsyncClient(ModelsImpl serviceClient) {
ClientModelAsyncClient(ClientModelsImpl serviceClient) {
this.serviceClient = serviceClient;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,25 @@
import com.azure.core.http.rest.RequestOptions;
import com.azure.core.http.rest.Response;
import com.azure.core.util.BinaryData;
import com.client.naming.implementation.ModelsImpl;
import com.client.naming.implementation.ClientModelsImpl;
import com.client.naming.models.ClientModel;
import com.client.naming.models.JavaModel;

/**
* Initializes a new instance of the synchronous NamingClient type.
*/
@ServiceClient(builder = NamingClientBuilder.class)
public final class ModelClient {
public final class ClientModelClient {
@Generated
private final ModelsImpl serviceClient;
private final ClientModelsImpl serviceClient;

/**
* Initializes an instance of ModelClient class.
* Initializes an instance of ClientModelClient class.
*
* @param serviceClient the service client implementation.
*/
@Generated
ModelClient(ModelsImpl serviceClient) {
ClientModelClient(ClientModelsImpl serviceClient) {
this.serviceClient = serviceClient;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@
@ServiceClientBuilder(
serviceClients = {
NamingClient.class,
ModelClient.class,
ClientModelClient.class,
UnionEnumClient.class,
NamingAsyncClient.class,
ModelAsyncClient.class,
ClientModelAsyncClient.class,
UnionEnumAsyncClient.class })
public final class NamingClientBuilder
implements HttpTrait<NamingClientBuilder>, ConfigurationTrait<NamingClientBuilder> {
Expand Down Expand Up @@ -262,13 +262,13 @@ public NamingAsyncClient buildAsyncClient() {
}

/**
* Builds an instance of ModelAsyncClient class.
* Builds an instance of ClientModelAsyncClient class.
*
* @return an instance of ModelAsyncClient.
* @return an instance of ClientModelAsyncClient.
*/
@Generated
public ModelAsyncClient buildModelAsyncClient() {
return new ModelAsyncClient(buildInnerClient().getModels());
public ClientModelAsyncClient buildClientModelAsyncClient() {
return new ClientModelAsyncClient(buildInnerClient().getClientModels());
}

/**
Expand All @@ -292,13 +292,13 @@ public NamingClient buildClient() {
}

/**
* Builds an instance of ModelClient class.
* Builds an instance of ClientModelClient class.
*
* @return an instance of ModelClient.
* @return an instance of ClientModelClient.
*/
@Generated
public ModelClient buildModelClient() {
return new ModelClient(buildInnerClient().getModels());
public ClientModelClient buildClientModelClient() {
return new ClientModelClient(buildInnerClient().getClientModels());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,37 @@
import reactor.core.publisher.Mono;

/**
* An instance of this class provides access to all the operations defined in Models.
* An instance of this class provides access to all the operations defined in ClientModels.
*/
public final class ModelsImpl {
public final class ClientModelsImpl {
/**
* The proxy service used to perform REST calls.
*/
private final ModelsService service;
private final ClientModelsService service;

/**
* The service client containing this operation class.
*/
private final NamingClientImpl client;

/**
* Initializes an instance of ModelsImpl.
* Initializes an instance of ClientModelsImpl.
*
* @param client the instance of the service client containing this operation class.
*/
ModelsImpl(NamingClientImpl client) {
this.service = RestProxy.create(ModelsService.class, client.getHttpPipeline(), client.getSerializerAdapter());
ClientModelsImpl(NamingClientImpl client) {
this.service
= RestProxy.create(ClientModelsService.class, client.getHttpPipeline(), client.getSerializerAdapter());
this.client = client;
}

/**
* The interface defining all the services for NamingClientModels to be used by the proxy service to perform REST
* calls.
* The interface defining all the services for NamingClientClientModels to be used by the proxy service to perform
* REST calls.
*/
@Host("http://localhost:3000")
@ServiceInterface(name = "NamingClientModels")
public interface ModelsService {
@ServiceInterface(name = "NamingClientClientMo")
public interface ClientModelsService {
@Post("/client/naming/model/client")
@ExpectedResponses({ 204 })
@UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,17 @@ public SerializerAdapter getSerializerAdapter() {
}

/**
* The ModelsImpl object to access its operations.
* The ClientModelsImpl object to access its operations.
*/
private final ModelsImpl models;
private final ClientModelsImpl clientModels;

/**
* Gets the ModelsImpl object to access its operations.
* Gets the ClientModelsImpl object to access its operations.
*
* @return the ModelsImpl object.
* @return the ClientModelsImpl object.
*/
public ModelsImpl getModels() {
return this.models;
public ClientModelsImpl getClientModels() {
return this.clientModels;
}

/**
Expand Down Expand Up @@ -124,7 +124,7 @@ public NamingClientImpl(HttpPipeline httpPipeline) {
public NamingClientImpl(HttpPipeline httpPipeline, SerializerAdapter serializerAdapter) {
this.httpPipeline = httpPipeline;
this.serializerAdapter = serializerAdapter;
this.models = new ModelsImpl(this);
this.clientModels = new ClientModelsImpl(this);
this.unionEnums = new UnionEnumsImpl(this);
this.service = RestProxy.create(NamingClientService.class, this.httpPipeline, this.getSerializerAdapter());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.azure.core.util.BinaryData;
import com.azure.core.util.FluxUtil;
import com.parameters.bodyoptionality.implementation.BodyOptionalityClientImpl;
import com.parameters.bodyoptionality.implementation.models.RequiredImplicitRequest;
import com.parameters.bodyoptionality.models.BodyModel;
import reactor.core.publisher.Mono;

Expand Down Expand Up @@ -72,7 +73,7 @@ public Mono<Response<Void>> requiredExplicitWithResponse(BinaryData body, Reques
* }
* }</pre>
*
* @param bodyModel The bodyModel parameter.
* @param requiredImplicitRequest The requiredImplicitRequest parameter.
* @param requestOptions The options to configure the HTTP request before HTTP client sends it.
* @throws HttpResponseException thrown if the request is rejected by server.
* @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
Expand All @@ -82,8 +83,9 @@ public Mono<Response<Void>> requiredExplicitWithResponse(BinaryData body, Reques
*/
@Generated
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono<Response<Void>> requiredImplicitWithResponse(BinaryData bodyModel, RequestOptions requestOptions) {
return this.serviceClient.requiredImplicitWithResponseAsync(bodyModel, requestOptions);
public Mono<Response<Void>> requiredImplicitWithResponse(BinaryData requiredImplicitRequest,
RequestOptions requestOptions) {
return this.serviceClient.requiredImplicitWithResponseAsync(requiredImplicitRequest, requestOptions);
}

/**
Expand All @@ -109,7 +111,7 @@ public Mono<Void> requiredExplicit(BodyModel body) {
/**
* The requiredImplicit operation.
*
* @param bodyModel The bodyModel parameter.
* @param name The name parameter.
* @throws IllegalArgumentException thrown if parameters fail the validation.
* @throws HttpResponseException thrown if the request is rejected by server.
* @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
Expand All @@ -120,9 +122,11 @@ public Mono<Void> requiredExplicit(BodyModel body) {
*/
@Generated
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono<Void> requiredImplicit(BodyModel bodyModel) {
public Mono<Void> requiredImplicit(String name) {
// Generated convenience method for requiredImplicitWithResponse
RequestOptions requestOptions = new RequestOptions();
return requiredImplicitWithResponse(BinaryData.fromObject(bodyModel), requestOptions).flatMap(FluxUtil::toMono);
RequiredImplicitRequest requiredImplicitRequestObj = new RequiredImplicitRequest(name);
BinaryData requiredImplicitRequest = BinaryData.fromObject(requiredImplicitRequestObj);
return requiredImplicitWithResponse(requiredImplicitRequest, requestOptions).flatMap(FluxUtil::toMono);
}
}
Loading

0 comments on commit a0e9fe7

Please sign in to comment.