Cadl ProviderHub Library
This is a library provides additional functionality to aid in developing Azure ProviderHub service specifications.
NOTE: This library is being deprecated in favor of the
@azure-tools/cadl-azure-resource-manager
library. Please consult the Migration Guide and the cadl-azure-resource-manager README for more details on how to use the new library.
Concepts
Service definition
First thing is the global definition of the ProviderHub service. For that you can add the serviceTitle
, serviceVersion
and armProviderNamespace
decorator on your root namespace.
@armProviderNamespace
@service({title: "<service name>"})
version: "<service version>"
namespace <mynamespace>;
Example:
@armProviderNamespace
@service({
title: "Microsoft.MyService",
})
version: "2020-10-01-preview"
namespace Microsoft.MyService;
Models/Arm Resources
See Cadl Models docs for the basic on models.
ProviderHub is composed of resources. Cadl ProviderHub library makes it much easier to define the structure and endpoints of such resources.
- Define a model representing the
properties
of the ARM resource.
@doc("Properties of UserResource")
model UserResourceProperties {
@doc("The name of my resource")
name: string;
@doc("Details of my resource")
details?: string;
}
- Define a model representing the parameter that corresponds to the resource name. Other resource identity parameters, like
subscriptionId
andresourceGroupName
will automatically be added.
model UserResourceNameParameter {
@doc("UserResource resource name")
@path
userResourceName: string;
}
- Define the resource model as an Arm Tracked Resource
@doc("A UserResource")
@armResource({
path: "UserResources",
parameterType: AccountNameParameter,
collectionName: "UserResources",
})
model UserResource is TrackedResource<UserResourceProperties>;
This will now produce all the endpoints(get
, post
, put
, patch
and delete
, listByResourceGroup, listBySubscription) for a resource called UserResources
and the operations
endpoint for the service:
Method & Path | Description |
---|---|
GET /providers/Microsoft.MyService/operations |
List all operations for your service |
GET /subscriptions/{subscriptionId}/providers/Microsoft.MyService/userResources |
list all UserResource by subscription |
GET /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.MyService/userResources |
list all UserResource by resource group |
GET /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.MyService/userResources/{userResourceName} |
get item |
PUT /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.MyService/userResources/{userResourceName} |
insert item |
PATCH /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.MyService/userResources/{userResourceName} |
patch item |
DELETE /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.MyService/userResources/{userResourceName} |
delete item |
Reference
Types of resources and common models for defining arm resources
Name | Description |
---|---|
TrackedResource | Defines a normal ARM resource, where TProperties is the model of the properties
|
ProxyResource | Defines a proxy Proxy resource, where TProperties is the model of the properties
|
ExtensionResource | Defines an extension ARM resource, where TProperties is the model of the properties
|
x-ms-identifiers
For array type with object item , the x-ms-identifiers is used to the identifying properties, see x-ms-identifiers for detail. If the array type does not contain 'id' and no 'x-ms-identifiers' is specified explicitly, an "x-ms-identifiers" with empty array will be added for the array type by default. And there is a linter rule to check it and show below waring :
Missing identifying properties of objects in the array item, please add @extension('x-ms-identifiers',...) to specify it.
Sub resources
Azure Management resources can be a sub resource of another.
This can easily be defined by setting the parentResourceType
property on the @armResource
.
The value is the parent resource type(Model with the @armResource
decorator)
For example to create a new AddressResource
resource under the UserResource
defined above.
@doc("An AddressResource")
@armResource({
path: "AddressResources",
parameterType: AddressNameParameter,
collectionName: "AddressResource",
parentResourceType: UserResource,
})
model AddressResource is TrackedResource<AddressResourceProperties>;
Additional endpoints/operations
Some resources will provide more than the basic CRUD operations and will need to define a custom endpoint.
For that you can create a new namespace containing the operations and use the @armResourceOperations
decorator referencing the resource those operations belong to.
Example: To add a POST /notify
operation on the UserResource
.
@armResourceOperations(UserResource)
namespace Users {
@post("notify")
@doc("Send a notification to the user")
op notifyUser(...CommonResourceParameters): ArmResponse<bool> | ErrorResponse;
}
Response
Custom operations in ARM still need to respect the correct response schema. Cadl-providerhub provide some models to help with reusability and compliance.
Model | Code | Description |
---|---|---|
ArmResponse<T> |
200 | Base Arm 200 response. |
ArmCreatedResponse<T> |
201 | Resource created response |
ArmDeletedResponse |
200 | Resource deleted response |
ArmDeleteAcceptedResponse |
202 | Resource deletion in progress response |
ArmDeletedNoContentResponse |
204 | Resource deleted response |
Page<T> |
200 | Return a list of resource with ARM pagination |
ErrorResponse<T> |
x | Error response |
Parameters
Common parameters that can be used in operation
Model | In | Description |
---|---|---|
ApiVersionParameter |
query |
api-version parameter |
SubscriptionIdParameter |
path | Subscription ID path parameter |
ResourceGroupNameParameter |
path | Resource Group Name path parameter |
CommonResourceParameters |
path & query | Group of Api version, Subscription ID and Resource group parameter |
ResourceUriParameter |
path | Resource uri path parameter |
OperationIdParameter |
path | Operation Id path parameter |
Migration Guide
If you have been using this library to author Azure Resource Manager services, here is a short guide on how you can update your Cadl files to use the new @azure-tools/cadl-azure-resource-manager
library.
IMPORTANT: The @armResource
-based service definition model will be deprecated in an upcoming release of this library so please migrate to the new library as soon as possible!
In cadl-providerhub
, ARM resource types are defined as model types which have an @armResource
decorator applied:
@doc("An AddressResource")
@armResource({
path: "AddressResources",
parameterType: AddressNameParameter,
collectionName: "AddressResource",
parentResourceType: UserResource,
})
model AddressResource is TrackedResource<AddressResourceProperties> {}
This would define an AddressResource
tracked resource with all standard operations.
In cadl-azure-resource-manager
, the equivalent definition would be:
@doc("An AddressResource")
@parentResource(UserResource)
model AddressResource is TrackedResource<AddressResourceProperties> {
@key("addressName")
@segment("AddressResources")
name: string;
}
@armResourceOperations
interface AddressResource extends TrackedResourceOperations<AddressResource> {
}
Explaining the Changes
Previously, the @armResource
decorator would accept all necessary metadata for defining resource types and then generate the standard resource operations behind the scenes.
In the new model, it is no longer necessary to mark a resource type with @armResource
, but instead you must add a name property inside of your resource type which is marked with the @key
and @segment
decorators to replace the functionality of the parameterType
nd path
parameters to the old armResource
decorator.
Defining the resource type no longer automatically defines the standard lifecycle operations, either. You must now define an interface for your resource's operations which extends one or more of the Resource*<TResource>
interfaces defined in cadl-azure-resource-manager
. If you want all standard lifecycle operations, you only need to extend TrackedResourceOperations<TResource, TProperties>
. Otherwise, you can manually extend your interface from the standard resource operation interfaces:
ResourceRead<TResource>
ResourceCreate<TResource>
ResourceUpdate<TResource, TProperties>
ResourceDelete<TResource>
ResourceListBySubscription<TResource>
ResourceListByParent<TResource>
For ProxyResource
and ExtensionResource
types, a different set of interfaces are necessary:
-
ProxyResourceOperations<TResource>
-
ExtensionResourceOperations<TResource, TProperties>
: provides all standard extension resource operations -
ExtensionResourceRead<TResource>
-
ExtensionResourceCreate<TResource>
-
ExtensionResourceUpdate<TResource, TProperties>
-
ExtensionResourceDelete<TResource>
-
ExtensionResourceList<TResource>