TypeSpec provide operation templates that describe the request and response of standard resource
operations. A description of the options available for each resource template, and how to choose
which one is described in the sections below.
CreateOrUpdate (PUT), Update (Patch), Delete, and Action (POST) operations over a resource may be either synchronous or asynchronous. Synchronous operations complete before a response is returned. Asynchronous operations return an initial response before the operation fully completes, and support long-running operation (LRO) polling. The sections below describe the available templates for both synchronous and asynchronous variants of each operation.
Determining Which Resource Properties Appear in Lifecycle Operations
By default, any property that occurs in your resource model will also appear in the response to GET,
PUT, PATCH, and LIST operations, and in the request for PUT and PATCH operations. This does not work
for all properties. Some properties are calculated by the service and cannot be directly set by PUT
or PATCH (provisioningState, modification date, etc.). Some properties can only be set when creating
a resource, but always appear in responses (e.g. ‘location’). Some properties can only be set when
updating the resource, and appear in responses. Some properties (rarely) may be settable when
updating the resource via PUT or PATCH. To allow using a common resource model, but applying these
views of resources to determine how the resource appear in request and responses, TypeSpec
provides the visibility framework. You can see a complete representation of available visibilities
in the table
on Property Visibility and Other Constraints.
The sections below outline some common scenarios for designing properties with your operations in
mind.
Properties That Are Never Directly Set by the User
It is common to have properties that are calculated by the service or otherwise not directly set by
the user, examples include timestamps, dates, values that are only set by specific actions (on/off,
enabled/disabled, provisioningState). You want to make sure that these properties are marked so that
they will appear in responses and not requests. this is done using the @visibility(Lifecycle.Read)
decorator instance:
The check existence operation uses a HEAD request to efficiently determine whether a resource exists
without returning the resource body. This is useful when you only need to verify a resource’s
existence and do not need to retrieve its full representation.
The CreateOrUpdate operation may be synchronous (The operation may always complete before a response
is returned) or asynchronous (an initial response may be returned before the operation fully
completes).
Simple resources may have synchronous PUT operations. If a resource may need to perform additional
checks, creation of other dependent resources, or the like, it is best to use an Asynchronous API.
Asynchronous operations for PUT occur when the RP needs to perform additional validaton actions,
create other resources, or perform other tasks as part of resource creation or update that can
cause the operation to take longer than the length of a single request/response.
Operation
TypeSpec
Synchronous PUT
createOrUpdate is ArmResourceCreateOrReplaceSync<ResourceType>
Asynchronous PUT
createOrUpdate is ArmResourceCreateOrReplaceAsync<ResourceType>
In the TypeSpec in the table createOrUpdate is the name of the operation, which will be passed on
to clients, and ResourceType is the type of the resource being created (or updated)
ARM Requires that all Tracked resources implement PATCH for ARM tags, which are contained in the
envelope of every TrackedResource. ARM recommends that you also allow PATCH of other envelope
properties and resource-specific properties. Unless marked with a specific visibility, any property
in your rp-specific properties will be automatically included in the PATCH schema.
TypeSpec Provides both Synchronous and Asynchronous PATCH Operations, and allows you to specify a
PATCH for Resource tags only, a PATCH for all updateable properties, or a custom patch. Generally,
you should choose the patch for all updateable properties, unless you have a very good reason for
choosing another PATCH operation.
Operation Description
TypeSpec
Sync TagsOnly PATCH
update is ArmTagsPatchSync<ResourceType>
Async TagsOnly PATCH
update is ArmTagsPatchAsync<ResourceType>
Sync Custom Properties PATCH (recommended)
update is ArmCustomPatchSync<ResourceType, PatchRequestModel>
Async Custom Properties PATCH (recommended)
update is ArmCustomPatchAsync<ResourceType, PatchRequestModel>
Sync Lifecycle PATCH
update is ArmResourcePatchSync<ResourceType, ResourcePropertiesType>
Async Lifecycle PATCH
update is ArmResourcePatchAsync<ResourceType, ResourcePropertiesType>
The ArmCustomPatch* templates are the recommended choice for PATCH operations. They take the
resource type and your custom PATCH request type as parameters, giving you full control over the
PATCH schema. The ArmTagsPatch* templates take the resource type as a parameter and only allow
updating ARM tags.
Note: The ArmTagsPatch* and ArmResourcePatch* templates use implicit optionality, which
requires a suppression at the usage site:
Note: The ArmResourcePatch* templates are not recommended. They rely on Lifecycle.Update
visibility analysis to automatically determine which properties are included in the PATCH schema,
but this analysis is only performed by the typespec-autorest emitter and will not be replicated in
SDKs generated for the PATCH operation. Instead, spec authors should define a specific PATCH model
and use the ArmCustomPatch* templates.
The Delete operation may be synchronous (The operation may always complete before a response is
returned) or asynchronous (an initial response may be returned before the operation fully
completes).
Simple resources may have synchronous DELETE operations. If a resource needs to clean up other
resources or do other validations as part of delete, the delete operation may need to be
asynchronous.
Operation
TypeSpec
Synchronous Delete
delete is ArmResourceDeleteSync<ResourceType>
Asynchronous Delete
delete is ArmResourceDeleteWithoutOkAsync<ResourceType>
In the TypeSpec in the table delete is the name of the operation, which will be passed on to
clients, and ResourceType is the type of the resource being deleted.
Arm Resource list operations return a list of Tracked or Proxy Resources at a particular scope.
All resources should include a list operation at its immediate parent scope
For Tenant Resources, this is at the tenant scope
For Extension Resources, this is at the scope of resources they are extending
For Tracked Resources, this is at the resource group scope.
For Child Resources, this is at the scope of the resource parent.
Tracked resources must include a list operation at the Subscription level.
Operation
TypeSpec
ListByParent
listByWidget is ArmResourceListByParent<ResourceType>
ListBySubscription
listBySubscription is ArmListBySubscriptionScope<ResourceType>
ListAtScope
listAtScope is ArmResourceListAtScope<ResourceType>
The ArmListBySubscriptionScope template is used for listing a resource directly at the subscription
scope, generating a flat subscription-level path regardless of the resource’s parent hierarchy.
Use this instead of ArmListBySubscription when you need a subscription-level list operation for a child resource.
The ArmResourceListAtScope template is used when the scope of the list operation is determined by
the BaseParameters type parameter. This is useful for resources with custom scope requirements
that do not fit the standard parent or subscription scopes.
Custom actions define any operations over resources outside the simple CRUDL (Create< Read, Update,
Delete, List) or lifecycle operations described above. Any operation that returns data that is not
made up of resources, performs a prescriptive state change on the resource (cycling power,
upgrading, etc.), or any operation that does not fit into the operations described above should be
modelled as a resource action. Examples of resource actions include:
Operations that manage credentials associated with a resource
Operations that calculate statistics about resources
Operations that make specific state changes to resources (power cycle, upgrade, etc.)
Operations that manage credentials are a good example fo this category. TypeSpec defines synchronous
and asynchronous templates for actions that consume and produce information.
Operation
TypeSpec
Synchronous Resource Action
updateCredentials is ArmResourceActionSync<ResourceType, Request, Response>
Asynchronous Resource Action
updateCredentials is ArmResourceActionAsync<ResourceType, Request, Response>
Parameters to the template are the ResourceType, the model for the operation Request body, and the
model for the operation Response body.
Actions that take input but produce no output (state changing actions)
Operations that make state changes will often take some user configuration, and will return a
seccess code or an error code depending on success or failure. TypeSpec defines synchronous and
asynchronous operation templates for state changing actions.
Operation
TypeSpec
Synchronous NoContent Action
updateCredentials is ArmResourceActionNoContentSync<ResourceType, Request>
Asynchronous NoContent Action
updateCredentials is ArmResourceActionNoResponseContentAsync<ResourceType, Request>
Parameters to the template are the ResourceType and the model for the operation Request body.
Actions that take no input but produce output (data retrieval actions)
Some operations return data or paged lists of data. TypeSpec does not yet provide templates for
these kinds of actions, but here are two templates that you could reuse in your own specification,
described in the next section of the document:
Provider actions are operations that are not scoped to a specific resource instance but instead
operate at the provider level. These are useful for operations like performing tenant-wide
configuration or subscription-level actions that are not tied to a particular resource.
Operation
TypeSpec
Synchronous Provider Action
myAction is ArmProviderActionSync<Request, Response>
Asynchronous Provider Action
myAction is ArmProviderActionAsync<Request, Response>
Provider Action with custom scope
myAction is ArmProviderActionSync<Request, Response, SubscriptionActionScope>
Provider Action with no request
myAction is ArmProviderActionSync<void, Response>
By default, provider actions use TenantActionScope. You can specify a different scope such as
SubscriptionActionScope or ExtensionResourceActionScope using the Scope template parameter.
Some services provide operations to check name availability, either location-specific (locally) or
globally, especially if a resource name must be globally unique (such as when an exposed endpoint
uses the resource name in the url).
Operation
TypeSpec
Global Name Availability Check
checkGlobalName is checkGlobalNameAvailability<Request, Response, AdditionalParams>
Local Name Availability Check
checkLocalName is checkLocalNameAvailability<Request, Response, AdditionalParams>
Custom Name Availability Check
customNameCheck is checkNameAvailability<ScopeParameters, Request, Response, AdditionalParams>
checkGlobalNameAvailability and checkLocalNameAvailability have default values that allow them
to be used without specifying any template parameters. checkNameAvailability requires the
ScopeParameters template parameter, which describes the parameters which define the scope of the
name check request. For reference, the following table shows the ScopeParameters for the standard
templates:
TypeSpec operation templates provide a simple mechanism for producing the most common operation
patterns in ARM, using best practices and conforming to ARM RPC guidelines. However, sometimes a
service has special requirements for operations that fall outside these boundaries. The
Azure.ResourceManager.Foundations namespace provides lower level building blocks that can be used
to produce operations and operation templates.
The building blocks are described in the sections below:
Custom operations in ARM still need to respect the correct response schema. This library provides
standard ARM response types to help with reusability and compliance.
ARM long-running operations (LROs) use operation status endpoints to allow clients to poll for the
status of an async operation. The GetResourceOperationStatus operation template provides a
standard way to expose these endpoints, and ArmOperationStatus provides the response model.
ArmOperationStatus is a response model that represents the status of an async operation. The id
field is not marked as a path parameter, so it is always included in the response body. This makes
it suitable for use as both the status monitor type and as the final LRO result.
GetResourceOperationStatus is a GET operation template for operation status endpoints. It supports
all four standard ARM path patterns through its Scope parameter. Use the appropriate scope model to
select the desired path:
Scope
Path pattern
TenantActionScope (default)
GET /providers/{ns}/operationStatuses/{operationId}
SubscriptionActionScope
GET /subscriptions/{sub}/providers/{ns}/operationStatuses/{operationId}
TenantLocationActionScope
GET /providers/{ns}/locations/{loc}/operationStatuses/{operationId}
SubscriptionLocationActionScope
GET /subscriptions/{sub}/providers/{ns}/locations/{loc}/operationStatuses/{operationId}