Skip to content

Commit

Permalink
refactor(http-client-csharp): remove BodyMediaType (#6119)
Browse files Browse the repository at this point in the history
- remove `BodyMediaType`
- remove corresponding properties in input models:
  - `InputOperation.RequestBodyMediaType`
  - `OperationResponse.BodyMediaType`
- regen test/sample

part of #4215

---------

Co-authored-by: Mingzhe Huang (from Dev Box) <mingzhehuang@microsoft.com>
  • Loading branch information
archerzz and Mingzhe Huang (from Dev Box) authored Mar 4, 2025
1 parent e262599 commit 7c5aabe
Showing 77 changed files with 3 additions and 1,573 deletions.
19 changes: 0 additions & 19 deletions packages/http-client-csharp/emitter/src/lib/operation-converter.ts
Original file line number Diff line number Diff line change
@@ -19,7 +19,6 @@ import { getDeprecated, isErrorModel, NoTarget } from "@typespec/compiler";
import { HttpStatusCodeRange } from "@typespec/http";
import { getResourceOperation } from "@typespec/rest";
import { CSharpEmitterContext } from "../sdk-context.js";
import { BodyMediaType } from "../type/body-media-type.js";
import { collectionFormatToDelimMap } from "../type/collection-format.js";
import { HttpResponseHeader } from "../type/http-response-header.js";
import { InputConstant } from "../type/input-constant.js";
@@ -71,7 +70,6 @@ export function fromSdkServiceMethod(
Parameters: [...parameterMap.values()],
Responses: [...responseMap.values()],
HttpMethod: parseHttpRequestMethod(method.operation.verb),
RequestBodyMediaType: getBodyMediaType(method.operation.bodyParam?.type),
Uri: uri,
Path: method.operation.path,
ExternalDocsUrl: getExternalDocs(sdkContext, method.operation.__raw.operation)?.url,
@@ -221,7 +219,6 @@ function loadLongRunningOperation(
method.lroMetadata.finalResponse?.envelopeResult !== undefined
? fromSdkModelType(sdkContext, method.lroMetadata.finalResponse.envelopeResult)
: undefined,
BodyMediaType: BodyMediaType.Json,
} as OperationResponse,
ResultPath: method.lroMetadata.finalResponse?.resultPath,
};
@@ -237,7 +234,6 @@ function fromSdkHttpOperationResponses(
responses.set(r, {
StatusCodes: toStatusCodesArray(range),
BodyType: r.type ? fromSdkType(sdkContext, r.type) : undefined,
BodyMediaType: BodyMediaType.Json,
Headers: fromSdkServiceResponseHeaders(sdkContext, r.headers),
IsErrorResponse: r.type !== undefined && isErrorModel(sdkContext.program, r.type.__raw!),
ContentTypes: r.contentTypes,
@@ -272,21 +268,6 @@ function toStatusCodesArray(range: number | HttpStatusCodeRange): number[] {
return statusCodes;
}

function getBodyMediaType(type: SdkType | undefined) {
if (type === undefined) {
return BodyMediaType.None;
}

if (type.kind === "model") {
return BodyMediaType.Json;
} else if (type.kind === "string") {
return BodyMediaType.Text;
} else if (type.kind === "bytes") {
return BodyMediaType.Binary;
}
return BodyMediaType.None;
}

function getRequestMediaTypes(op: SdkHttpOperation): string[] | undefined {
const contentTypes = op.parameters.filter(
(p) => p.kind === "header" && p.serializedName.toLocaleLowerCase() === "content-type",
28 changes: 0 additions & 28 deletions packages/http-client-csharp/emitter/src/type/body-media-type.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

import { DecoratorInfo } from "@azure-tools/typespec-client-generator-core";
import { BodyMediaType } from "./body-media-type.js";
import { InputHttpOperationExample } from "./input-examples.js";
import { InputParameter } from "./input-parameter.js";
import { OperationLongRunning } from "./operation-long-running.js";
@@ -26,7 +25,6 @@ export interface InputOperation {
Parameters: InputParameter[];
Responses: OperationResponse[];
HttpMethod: RequestMethod;
RequestBodyMediaType: BodyMediaType;
Uri: string;
Path: string;
ExternalDocsUrl?: string;
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

import { BodyMediaType } from "./body-media-type.js";
import { HttpResponseHeader } from "./http-response-header.js";
import { InputType } from "./input-type.js";

export interface OperationResponse {
StatusCodes: number[];
BodyType?: InputType;
BodyMediaType: BodyMediaType;
Headers: HttpResponseHeader[];
ContentTypes?: string[];
IsErrorResponse: boolean;
Original file line number Diff line number Diff line change
@@ -10,65 +10,6 @@ namespace Microsoft.TypeSpec.Generator.ClientModel
{
internal static class FormattableStringHelpers
{
private static readonly Regex ContentTypeRegex = new Regex(@"(application|audio|font|example|image|message|model|multipart|text|video|x-(?:[0-9A-Za-z!#$%&'*+.^_`|~-]+))\/([0-9A-Za-z!#$%&'*.^_`|~-]+)\s*(?:\+([0-9A-Za-z!#$%&'*.^_`|~-]+))?\s*(?:;.\s*(\S*))?", RegexOptions.Compiled);

public static BodyMediaType ToMediaType(string contentType)
{
var matches = ContentTypeRegex.Matches(contentType);
if (matches.Count == 0)
{
throw new NotSupportedException($"Content type {contentType} is not supported.");
}

var type = matches[0].Groups[1].Value;
var subType = matches[0].Groups[2].Value;
var suffix = matches[0].Groups[3].Value;
var parameter = matches[0].Groups[4].Value;

var typeSubs = contentType.Split('/');
if (typeSubs.Length != 2)
{
throw new NotSupportedException($"Content type {contentType} is not supported.");
}

if ((subType == "json" || suffix == "json") && (type == "application" || type == "text") && suffix == "" && parameter == "")
{
return BodyMediaType.Json;
}

if ((subType == "xml" || suffix == "xml") && (type == "application" || type == "text"))
{
return BodyMediaType.Xml;
}

if (type == "audio" || type == "image" || type == "video" || subType == "octet-stream" || parameter == "serialization=Avro")
{
return BodyMediaType.Binary;
}

if (type == "application" && subType == "formEncoded")
{
return BodyMediaType.Form;
}

if (type == "multipart" && subType == "form-data")
{
return BodyMediaType.Multipart;
}

if (type == "application")
{
return BodyMediaType.Binary;
}

if (type == "text")
{
return BodyMediaType.Text;
}

throw new NotSupportedException($"Content type {contentType} is not supported.");
}

public static FormattableString Empty => $"";

[return: NotNullIfNotNull(nameof(s))]

This file was deleted.

Original file line number Diff line number Diff line change
@@ -21,7 +21,6 @@ public InputOperation(
IReadOnlyList<InputParameter> parameters,
IReadOnlyList<OperationResponse> responses,
string httpMethod,
BodyMediaType requestBodyMediaType,
string uri,
string path,
string? externalDocsUrl,
@@ -42,7 +41,6 @@ public InputOperation(
Parameters = parameters;
Responses = responses;
HttpMethod = httpMethod;
RequestBodyMediaType = requestBodyMediaType;
Uri = uri;
Path = path;
ExternalDocsUrl = externalDocsUrl;
@@ -65,7 +63,6 @@ public InputOperation() : this(
parameters: Array.Empty<InputParameter>(),
responses: Array.Empty<OperationResponse>(),
httpMethod: string.Empty,
requestBodyMediaType: BodyMediaType.None,
uri: string.Empty,
path: string.Empty,
externalDocsUrl: null,
@@ -87,7 +84,6 @@ public InputOperation() : this(
public IReadOnlyList<InputParameter> Parameters { get; internal set; }
public IReadOnlyList<OperationResponse> Responses { get; internal set; }
public string HttpMethod { get; internal set; }
public BodyMediaType RequestBodyMediaType { get; internal set; }
public string Uri { get; internal set; }
public string Path { get; internal set; }
public string? ExternalDocsUrl { get; internal set; }
Original file line number Diff line number Diff line change
@@ -11,21 +11,19 @@ namespace Microsoft.TypeSpec.Generator.Input
/// </summary>
public sealed class OperationResponse
{
public OperationResponse(IReadOnlyList<int> statusCodes, InputType? bodyType, BodyMediaType bodyMediaType, IReadOnlyList<OperationResponseHeader> headers, bool isErrorResponse, IReadOnlyList<string> contentTypes)
public OperationResponse(IReadOnlyList<int> statusCodes, InputType? bodyType, IReadOnlyList<OperationResponseHeader> headers, bool isErrorResponse, IReadOnlyList<string> contentTypes)
{
StatusCodes = statusCodes;
BodyType = bodyType;
BodyMediaType = bodyMediaType;
Headers = headers;
IsErrorResponse = isErrorResponse;
ContentTypes = contentTypes;
}

public OperationResponse() : this(Array.Empty<int>(), null, BodyMediaType.None, Array.Empty<OperationResponseHeader>(), false, Array.Empty<string>()) { }
public OperationResponse() : this(Array.Empty<int>(), null, Array.Empty<OperationResponseHeader>(), false, Array.Empty<string>()) { }

public IReadOnlyList<int> StatusCodes { get; }
public InputType? BodyType { get; }
public BodyMediaType BodyMediaType { get; }
public IReadOnlyList<OperationResponseHeader> Headers { get; }
public bool IsErrorResponse { get; }
public IReadOnlyList<string> ContentTypes { get; }
Original file line number Diff line number Diff line change
@@ -45,7 +45,6 @@ public override void Write(Utf8JsonWriter writer, InputOperation value, JsonSeri
IReadOnlyList<InputParameter>? parameters = null;
IReadOnlyList<OperationResponse>? responses = null;
string? httpMethod = null;
BodyMediaType requestBodyMediaType = default;
string? uri = null;
string? path = null;
string? externalDocsUrl = null;
@@ -69,7 +68,6 @@ public override void Write(Utf8JsonWriter writer, InputOperation value, JsonSeri
|| reader.TryReadWithConverter(nameof(InputOperation.Parameters), options, ref parameters)
|| reader.TryReadWithConverter(nameof(InputOperation.Responses), options, ref responses)
|| reader.TryReadString(nameof(InputOperation.HttpMethod), ref httpMethod)
|| reader.TryReadWithConverter(nameof(InputOperation.RequestBodyMediaType), options, ref requestBodyMediaType)
|| reader.TryReadString(nameof(InputOperation.Uri), ref uri)
|| reader.TryReadString(nameof(InputOperation.Path), ref path)
|| reader.TryReadString(nameof(InputOperation.ExternalDocsUrl), ref externalDocsUrl)
@@ -97,7 +95,6 @@ public override void Write(Utf8JsonWriter writer, InputOperation value, JsonSeri
operation.Parameters = parameters ?? Array.Empty<InputParameter>();
operation.Responses = responses ?? Array.Empty<OperationResponse>();
operation.HttpMethod = httpMethod ?? throw new JsonException("InputOperation must have HttpMethod");
operation.RequestBodyMediaType = requestBodyMediaType;
operation.Uri = uri ?? throw new JsonException("InputOperation must have Uri");
operation.Path = path ?? throw new JsonException("InputOperation must have Path");
operation.ExternalDocsUrl = externalDocsUrl;
Original file line number Diff line number Diff line change
@@ -30,7 +30,6 @@ private OperationResponse CreateOperationResponse(ref Utf8JsonReader reader, str
var isFirstProperty = id == null;
IReadOnlyList<int>? statusCodes = null;
InputType? bodyType = null;
string? bodyMediaTypeString = null;
IReadOnlyList<OperationResponseHeader>? headers = null;
bool isErrorResponse = default;
IReadOnlyList<string>? contentTypes = null;
@@ -39,7 +38,6 @@ private OperationResponse CreateOperationResponse(ref Utf8JsonReader reader, str
var isKnownProperty = reader.TryReadReferenceId(ref isFirstProperty, ref id)
|| reader.TryReadWithConverter(nameof(OperationResponse.StatusCodes), options, ref statusCodes)
|| reader.TryReadWithConverter(nameof(OperationResponse.BodyType), options, ref bodyType)
|| reader.TryReadString(nameof(OperationResponse.BodyMediaType), ref bodyMediaTypeString)
|| reader.TryReadWithConverter(nameof(OperationResponse.Headers), options, ref headers)
|| reader.TryReadBoolean(nameof(OperationResponse.IsErrorResponse), ref isErrorResponse)
|| reader.TryReadWithConverter(nameof(OperationResponse.ContentTypes), options, ref contentTypes);
@@ -54,12 +52,7 @@ private OperationResponse CreateOperationResponse(ref Utf8JsonReader reader, str
contentTypes ??= [];
headers ??= [];

if (!Enum.TryParse<BodyMediaType>(bodyMediaTypeString, true, out var bodyMediaType))
{
throw new JsonException();
}

var result = new OperationResponse(statusCodes, bodyType, bodyMediaType, headers, isErrorResponse, contentTypes);
var result = new OperationResponse(statusCodes, bodyType, headers, isErrorResponse, contentTypes);

if (id != null)
{
Original file line number Diff line number Diff line change
@@ -232,7 +232,6 @@ public static InputOperation Operation(
parameters is null ? [] : [.. parameters],
responses is null ? [OperationResponse()] : [.. responses],
httpMethod,
BodyMediaType.Json,
uri,
path,
null,
@@ -250,7 +249,6 @@ public static OperationResponse OperationResponse(IEnumerable<int>? statusCodes
return new OperationResponse(
statusCodes is null ? [200] : [.. statusCodes],
bodytype,
BodyMediaType.Json,
[],
false,
["application/json"]);
Loading

0 comments on commit 7c5aabe

Please sign in to comment.