Skip to content

Method Inputs

This document outlines the method input signatures that language emitters will generate.

Basic

HTTP Get

@get
op get(): User;
def get() -> User:
...

HTTP Post

@post
op post(@body body: User): void;

For model inputs, Python automatically generates an overload that allows SDK users to input through a file stream.

@overload
def post(body: User, **kwargs: Any) -> None:
...
@overload
def post(body: JSON, **kwargs: Any) -> None:
...
@overload
def post(body: IO[bytes], **kwargs: Any) -> None:
...
def post(body: [User, JSON, IO[bytes]], **kwargs: Any) -> None:
...

Spread

Please exercise caution when using the spread feature.

  • The model to be spread should have fewer than 6 settable properties. See simple methods.
  • The model to be spread should remain stable across api-versions. Adding an optional property across api-versions could result in one additional method overload in SDK client.
  • The model to be spread should not be used in JSON Merge Patch.

Alias

alias User = {
firstName: string;
lastName: string;
};
@post
op upload(...User): void;

For Python, we will also generate the overloads described in the HTTP Post section, but will omit them for brevity.

def upload(first_name: str, last_name: str) -> None:
...

Alias with @header/@query/@path properties

alias User = {
@path id: string;
firstName: string;
lastName: string;
};
op upload(...User): void;

For Python, we will also generate the overloads described in the HTTP Post section, but will omit them for brevity.

def upload(self, id: str, first_name: str, last_name: str, *, content_type: str = "application/json") -> None:
...

Named model

model User {
firstName: string;
lastName: string;
}
op upload(...User): void;

For Python, we will also generate the overloads described in the HTTP Post section, but will omit them for brevity.

def upload(self, first_name: str, last_name: str, *, content_type: str = "application/json") -> None:
...

Model with @body property

model User {
firstName: string;
lastName: string;
}
model UserRequest {
@body user: User;
}
op upload(...UserRequest): void;

For Python, we will also generate the overloads described in the HTTP Post section, but will omit them for brevity.

def upload(self, body: [User, JSON, IO[bytes]], *, content_type: str = "application/json") -> None:
...

Model with @header/@query/@path properties

model BlobProperties {
@path
name: string;
@header testHeader: string;
}
@route("blob_properties/{name}")
op getBlobProperties(...BlobProperties): void;

For Python, we will also generate the overloads described in the HTTP Post section, but will omit them for brevity.

def get_blob_properties(self, name: str, *, test_header: string, content_type: str = "application/json") -> None:
...

Model mixed with normal and @header/@query/@path properties

model Schema {
@header contentType: "application/json";
schema: bytes;
}
@post
op register(...Schema): void;

For Python, we will also generate the overloads described in the HTTP Post section, but will omit them for brevity.

class Schema:
schema: bytes
def register(self, body: [Schema, JSON, IO[bytes]], *, content_type: str = "application/json") -> None:
...

Using Azure.Core.ResourceOperations template

Resource create and update operations are not impacted by spread since they all have explicit defined body parameter. Only resource action operations are impacted by spread.

If the action parameter is a model, then the model will be spread.

@resource("widgets")
model Widget {
@key("widgetName")
name: string;
}
model RepairInfo {
problem: string;
contact: string;
}
model RepairResult {
reason: string;
info: string;
}
alias Operations = Azure.Core.ResourceOperations<{}>;
op scheduleRepairs is Operations.ResourceAction<Widget, RepairInfo, RepairResult>;

For Python, we will also generate the overloads described in the HTTP Post section, but will omit them for brevity.

class RepairInfo:
problem: str
contact: str
class RepairResult:
reason: str
info: str
def scheduleRepairs(self, widget_name: str, problem: str, contact: str, *, content_type: str = "application/json") -> RepairResult:
...

If you want to keep the model, you have two options to prevent spreading:

  1. @override
  2. If you don’t want to do client customizations, you could use a wrapper to explicitly set the body to prevent spread.

1. @override

The @override decorator allows you to replace the default client method generated by TCGC based on your service definition.

If your service definition spreads a model into the method signature, but you prefer that the generated client SDKs maintain the model intact, the @override decorator provides a solution.

Additionally, you can specify a language scope to limit the changes to a specific language emitter.

client.tsp
namespace Widget.Client;
op scheduleRepairs(
body: RepairInfo,
`api-version`: Azure.Core.Foundations.ApiVersionParameter,
): RepairResult;
@@override(Widget.Service.scheduleRepairs, Widget.Client.scheduleRepairs);

2. wrapper

If you prefer not to implement customizations in client.tsp, you can add @bodyRoot to the input in main.tsp prior to passing the model to the template.

main.tsp
namespace Widget.Service;
@resource("widgets")
model Widget {
@key("widgetName")
name: string;
}
model RepairInfo {
problem: string;
contact: string;
}
model RepairResult {
reason: string;
info: string;
}
alias Operations = Azure.Core.ResourceOperations<{}>;
alias BodyParameter<
T,
TName extends valueof string = "body",
TDoc extends valueof string = "Body parameter."
> = {
@doc(TDoc)
@friendlyName(TName)
@bodyRoot
body: T;
};
op scheduleRepairs is Operations.ResourceAction<Widget, BodyParameter<RepairInfo>, RepairResult>;

For Python, we will also generate the overloads described in the HTTP Post section, but will omit them for brevity.

class RepairInfo:
problem: str
contact: str
class RepairResult:
reason: str
info: str
def scheduleRepairs(self, body: [Schema, JSON, IO[bytes]], *, content_type: str = "application/json") -> RepairResult:
...