Skip to content

ARM Resource Operations

TrackedResource

OperationRecommendedRequiredTypeSpec Representation
GETYesYesget is ArmResourceRead<Resource>;
CreateOrUpdate (PUT)YesYescreateOrUpdate is ArmResourceCreateOrUpdateAsync<Resource>;
Tags Update (PATCH)NoYes*update is ArmResourceTagsPatchSync<Resource>;
Full Update (PATCH)YesNo*update is ArmResourcePatchSync<Resource, ResourceProperties>;
DeleteYesYesdelete is ArmResourceDeleteSync<Resource>;
List by ResourceGroupYesYeslistByResourceGroup is ArmResourceListByParent<Resource>;
List by SubscriptionYesYeslistBySubscription is ArmResourceListBySubscription<Resource>;

* Arm requires that, at minimum, a TrackedResource can update Tags. A Full PATCH of all updateable resource properties is preferred.

Proxy Resource

OperationRecommendedRequiredTypeSpec Representation
GETYesYesget is ArmResourceRead<Resource>;
CreateOrUpdate (PUT)YesNo*createOrUpdate is ArmResourceCreateOrUpdateAsync<Resource>;
Update (PATCH)YesNoupdate is ArmResourcePatchSync<Resource, ResourceProperties>;
DeleteYesNo*delete is ArmResourceDeleteSync<Resource>;
List by ParentYesYeslistByParent is ArmResourceListByParent<Resource>;

* Note that, if a resource implements Create, it is highly recommended that it implement delete as well, and vice-versa.

TypeSpec Operation Templates and Interface Templates

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.

Synchronous and Asynchronous APIs

CreateOrUpdate (PUT), Update (Patch), Delete, and Action (POST) operations over a resource may

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("read") decorator instance:

@visibility("read")
provisioningState: ProvisioningState;

Resource Get Operations

Get is the operation to retrieve a single resource TypeSpec provides a single operation template for GET:

op get is ArmResourceRead<MyResource>;
  • get: The name of the operation passed on to clients.
  • Resource: A reference to your resource type.

Resource CreateOrUpdate Operations (PUT)

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.
OperationTypeSpec
Synchronous PUTcreateOrUpdate is ArmResourceCreateOrReplaceSync<ResourceType>
Asynchronous PUTcreateOrUpdate 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)

Resource Update Operations (PATCH)

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 fro choosing another PATCH operation.

Operation DescriptionTypeSpec
Sync Updateable Properties PATCHupdate is ArmResourcePatchSync<ResourceType, ResourceProperties>
Async Updateable Properties PATCHupdate is ArmResourcePatchAsync<ResourceType, ResourceProperties>
Sync TagsOnly PATCHupdate is ArmTagsPatchSync<ResourceType>
Async TagsOnly PATCHupdate is ArmTagsPatchAsync<ResourceType>
Sync Custom PATCHupdate is ArmCustomPatchSync<ResourceType, PatchRequest>
Async Custom PATCHupdate is ArmCustomPatchAsync<ResourceType, PatchRequest>

The ArmResourcePatch* templates take the resource type and the resource properties type as parameters. The ArmTagsPatch* templates take the resource type as a parameter. The ArmCustomPatch* templates take the resource type and your custom PATCH request type as parameters.

Resource Delete Operations (DELETE)

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.

OperationTypeSpec
Synchronous Deletedelete is ArmResourceDeleteSync<ResourceType>
Asynchronous Deletedelete 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.

Resource List Operations (GET)

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.
OperationTypeSpec
ListByParentlistByWidget is ArmResourceListByParent<ResourceType>
ListBySubscriptionlistBySubscription is ArmResourceListBySubscription<ResourceType>

Resource Actions (POST)

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.)

Actions that take input and output

Operations that manage credentials are a good example fo this category. TypeSpec defines synchronous and asynchronous templates for actions that consume and produce information.

OperationTypeSpec
Synchronous Resource ActionupdateCredentials is ArmResourceActionSync<ResourceType, Request, Response>
Asynchronous Resource ActionupdateCredentials 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.

OperationTypeSpec
Synchronous NoContent ActionupdateCredentials is ArmResourceActionNoContentSync<ResourceType, Request>
Asynchronous NoContent ActionupdateCredentials 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:

Check Name Operations

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).

OperationTypeSpec
Global Name Availability CheckcheckGlobalName is checkGlobalNameAvailability<TRequest, TResponse, TAdditionalParams>
Local Name Availability CheckcheckLocalName is checkLocalNameAvailability<TRequest, TResponse, TAdditionalParams>
Custom Name Availability CheckcustomNameCheck is checkNameAvailability<TScopeParameters, TRequest, TResponse, TAdditionalParams>

checkGlobalNameAvailability and checkLocalNameAvailability have default values that allow them to be used without specifying any template parameters. checkNameAvailability requires the TScopeParameters template parameter, which describes the parameters which define the scope of the name check request. For reference, the following table shows the TScopeParameters for the standard templates:

OperationScope Parameters
Global Name Availability CheckSubscriptionIdParameter, DefaultProviderNamespace
Local Name Availability CheckSubscriptionIdParameter, DefaultProviderNamespace, LocationParameter

Writing Custom Operations

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:

ARM Response Types

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.

ModelCodeDescription
ArmResponse<T>200Base Arm 200 response.
ArmResourceUpdatedResponse<T>200Resource updated (PUT) response.
ArmResourceCreatedResponse<T>201Resource created response for an lro.
ArmResourceCreatedSyncResponse<T>201Resource created synchronously.
ArmAcceptedResponse202Base Arm Accepted response.
ArmNoContentResponse204Base Arm No Content response.
ArmDeletedResponse200Resource deleted response.
ArmDeleteAcceptedResponse202Resource deletion in progress response.
ResourceListResult<T>200Return a list of resource with ARM pagination
ErrorResponsexError response

Common Operation Parameters

There are a number of model types which specify common parameters which are used in resource type operations:

ModelInDescription
ApiVersionParameterqueryapi-version parameter
SubscriptionIdParameterpathSubscription ID path parameter
ResourceGroupNameParameterpathResource Group Name path parameter
ResourceInstanceParameters<T>path & queryIdentity parameters for a resource, with api-version
ResourceParentParameters<T>path & queryIdentity Parameters for listing by parent, with api-version
ResourceUriParameterpathResource uri path parameter for Extension resources
OperationIdParameterpathOperation Id path parameter

Synchronous List Action

Here is a sample template for resource list actions that return synchronously, using the common building blocks.

// Template definition
@autoRoute
@armResourceAction(TResource)
@post
op ArmResourceListActionSync<TResource extends ArmResource, TResponse extends object>(
...ResourceInstanceParameters<TResource, TBaseParameters>,
): ArmResponse<TResponse> | ErrorResponse;
// Usage
// The model for each data record
model Widget {
name: string;
color: string;
}
@armResourceOperations(MyResource)
interface MyResourceOperations {
// ResourceListResult<T> produces a Pageable list of T
listWidgets is ArmResourceListActionSync<MyResource, ResourceListResult<Widget>>;
}

Asynchronous List Action

Here is a sample template for resource list actions that return asynchronously, using the common building blocks.

// Template definition
@autoRoute
@armResourceAction(TResource)
@post
op ArmResourceListActionAsync<TResource extends ArmResource, TResponse extends object>(
...ResourceInstanceParameters<TResource, TBaseParameters>,
): ArmResponse<TResponse> | ArmAcceptedResponse | ErrorResponse;
// Usage
// The model for each data record
model Widget {
name: string;
color: string;
}
@armResourceOperations(MyResource)
interface MyResourceOperations {
// ResourceListResult<T> produces a Pageable list of T
listWidgets is ArmResourceListActionAsync<MyResource, ResourceListResult<Widget>>;
}