Nutmeg Pumpkin Macchiato

    @azure-tools/cadl-azure-core
    TypeScript icon, indicating that this package has built-in type declarations

    0.7.0 • Public • Published

    Cadl Azure Core Library

    This package provides Cadl decorators, models and interfaces to describe Azure services. With models, decorators and interfaces defined in Azure.Core, you will be able to define Azure resources and operations using standard patterns and best practices with ease.

    Getting Started

    Before using this library, you should familiarize yourself with the Cadl language and tools. You can do this by reading the Cadl tutorial.

    Install

    In your Cadl project root

    npm install @azure-tools/cadl-azure-core

    Usage

    import "@azure-tools/cadl-azure-core";
    
    using Azure.Core;
    

    Create a new Cadl project

    Create a new project using cadl init

    Use the cadl init command, specifying the azure core template at 'https://aka.ms/cadl/core-init' to create a new npm project for your cadl spec

    C:\myService>cadl init https://aka.ms/cadl/core-init
    Cadl compiler v0.34.0
    
    √ Please select a template » Azure Data Plane Service
    √ Project name ... myService
    √ Update the libraries? » @cadl-lang/rest, @cadl-lang/versioning, @azure-tools/cadl-autorest, @azure-tools/cadl-azure-core
    Cadl init completed. You can run `cadl install` now to install dependencies.
    

    You can then execute cadl install or npm install to install the cadl compiler and libraries.

    How to specify a version of Azure.Core

    cadl-azure-core is a versioned Cadl library. This means that, even as the Cadl portions of the cadl-azure-core library are updated, you can anchor each version of your spec to a specific version. This is done by decorating your service namespace with the @versionedDependency decorator from the cadl-versioning library. The current version of the cadl-azure-core library is Azure.Core.Versions.v1_0_Preview_1:

    @versionedDependency(Azure.Core.Versions.v1_0_Preview_1)
    @server(
      "{serviceUri}",
      "My service Uri",
      {
        serviceUri: string,
      }
    )
    namespace Azure.MyService;
    

    How to specify a version of Azure.Core for each version of your spec

    If your spec has multiple versions, you will need to specify the version of cadl-azure-core that was used for each version in your spec:

    @versionedDependency(
      [
        [Azure.MyService.Versions.v2021_06_13_preview, Azure.Core.Versions.v1_0_Preview_1],
        [Azure.MyService.Versions.v2022_04_30_preview, Azure.Core.Versions.v1_0_Preview_1]
      ]
    )
    @server(
      "{serviceUri}",
      "My service Uri",
      {
        serviceUri: string,
      }
    )
    @versioned(Azure.MyService.Versions)
    namespace Azure.MyService;
    
    enum Versions {
      v2021_06_13_preview: "2021-06-13-preview",
      v2022_04_30_preview: "2022-04-30-preview",
    }
    

    Define resource types

    Using Cadl.Rest ("@cadl-lang/rest") you can define a resource:

    using Cadl.Rest;
    
    @resource("widgets")
    model Widget {
      @key id: string;
      name: string;
    }
    

    Defining parent and child resources

    Using Cadl.Rest ("@cadl-lang/rest") you can create parent/child relationships between resource types using the @parentResource decorator when defining a resource type.

    For example, here's how you could create a new WidgetPart resource under the Widget defined above:

    @doc("A WidgetPart resource belonging to a Widget resource.")
    @resource("parts")
    @parentResource(Widget)
    model WidgetPart {
      @key("partName")
      name: string;
    
      @doc("The part number.")
      number: string;
    
      @doc("The part name.")
      partName: string;
    }
    
    op listWidgets is ResourceList<Widget>;
    op listParts is ResourceList<WidgetPart>;
    

    Define resource operations

    You can then use the basic building blocks in Azure.Core to define your operations or interface:

    op widgetUpsert is ResourceCreateOrUpdate<Widget>;
    op read is ResourceRead<Widget>;
    op list is ResourceList<Widget>;
    op listNonpaged is NonPagedResourceList<Widget>;
    

    You can also create long-running operations:

    op create is LongRunningResourceCreateWithServiceProvidedName<Widget>;
    op createReplace is LongRunningResourceCreateOrReplace<Widget>;
    op delete is LongRunningResourceDelete<Widget>;
    

    In addition to standard operations, you can define custom actions:

    model CustomOpParams is CustomParameters;
    model CustomOpResponse is CustomResponseProperties {
      message: string;
    }
    
    op customAction is ResourceAction<Widget, CustomOpParams, CustomOpResponse>;
    op customCollectionAction is ResourceCollectionAction<Widget, CustomOpParams, CustomOpResponse>;
    

    Customizing operations

    For all standard operations (except for ResourceAction and ResourceCollectionAction) you can customize the operation parameters and response body by passing TCustom to the operation template.

    model CustomParameters {
      @header
      "x-ms-special": string;
    
      @query
      nameHint: string;
    }
    
    model CustomResponseProperties {
      @header
      "x-ms-response-id": int32;
    }
    
    model ResourceReadCustomizations {
      parameters: CustomParameters;
      response: CustomResponseProperties;
    }
    
    op read is ResourceRead<Widget, ResourceReadCustomizations>;
    

    Define clients and subclients

    With a single Cadl spec you can define multiple clients by defining an enum and using the @client decorator. The @client decorator can be used on namespaces, interfaces or specific operations to give you course- to fine-grained control over which client your operations appear in.

    enum Clients { WidgetClient, PartsClient };
    
    @client(Clients.WidgetClient)
    namespace Widgets {
      ...
    }
    
    @client(Clients.PartsClient)
    namespace WidgetParts {
      ...
    }
    
    

    You can customize the client parameters using the @clientDefinition decorator and passing in a model type (including anonymous models):

    model ClientParameters {
      host: string;
      apiToken: string;
    }
    
    enum Clients {
      @clientDefinition({
        parameters: ClientParameters,
      })
      ServiceClient,
    }
    

    Finally, you can define a client/subclient relationship using the Subclient<T> operation template:

    enum Clients { WidgetClient, PartsClient };
    
    @client(Clients.WidgetClient)
    namespace Widgets {
      op getPartsClient is Subclient<Clients.PartsClient>;
    }
    
    @client(Clients.PartsClient)
    namespace WidgetParts {
      ...
    }
    
    

    This will expose a method like WidgetClient.getPartsClient which will return a PartsClient.

    Library Tour

    The @azure-tools/cadl-azure-core library defines the following artifacts:

    Models

    The @azure-tools/cadl-azure-core library defines the following models:

    Model Notes
    Page<TResource> Model for a paged resource. <TResource> is the model description of the item.
    PagedResultMetadata Contains the metadata associated with a Page<TResource>.
    RequestParameter<T> For long-running operations, identifies that a continuation operation request parameter is pulled from the original request. <T> is the property name on the original request.
    ResponseProperty<T> For long-running operations, identifies that a continuation operation request parameter is pulled from the response of the previous request. <T> is the property name on the previous response.
    LongRunningStates Identifies the long-running states associated with a long-running operation.
    OperationLinkMetadata Contains the metadata associated with an operation link.
    ClientTargets An alias for namespace, interfaces and/or operations.
    ClientDefinition Provides details about a client defined in a Cadl specification.

    Operations

    The @azure-tools/cadl-azure-core library defines these standard operation templates as basic building blocks that you can expose. You can use is to compose the operations to meet the exact needs of your APIs.

    For all of these operation templates, TResource is the resource model and TCustom allows customization of the operation parameters or response. TCustom, if provided, must extend the Azure.Core.Foundations.CustomizationFields model, which looks like:

    @doc("The expected shape of model types passed to the TCustom parameter of operation signatures.")
    model CustomizationFields {
      @doc("An object containing custom parameters that will be included in the operation.")
      parameters?: object;
    
      @doc("An object containing custom properties that will be included in the response.")
      response?: object;
    }
    
    Operation Notes
    ResourceCreateOrUpdate<TResource, TCustom> Resource PATCH operation.
    ResourceCreateOrReplace<TResource, TCustom> Resource PUT operation.
    ResourceCreateWithServiceProvidedName<TResource, TCustom> Resource POST operation.
    ResourceRead<TResource, TCustom> Resource GET operation.
    ResourceDelete<TResource, TCustom> Resource DELETE operation.
    ResourceList<TResource, TCustom> Resource LIST operation with server-driven paging.
    NonPagedResourceList<TResource, TCustom> Resource LIST operation without paging.
    ResourceAction<TResource, TParams, TResponse> Perform a custom action on a specific resource.
    ResourceCollectionAction<TResource, TParams, TResponse> Perform a custom action on a collection of resources.
    LongRunningResourceCreateOrReplace<TResource, TCustom> Long-running resource PUT operation.
    LongRunningResourceCreateOrUpdate<TResource, TCustom> Long-running resource PATCH operation.
    LongRunningResourceCreateWithServiceProvidedName<TResource, TCustom> Long-running resource POST operation.
    LongRunningResourceDelete<TResource, TCustom> Long-running resource DELETE operation.

    Decorators

    The @azure-tools/cadl-azure-core library defines the following decorators:

    Declarator Scope Usage
    @pagedResult models indicates model describes a paged result.
    @items model properties indicates model property that stores the items within a paged result.
    @nextLink model properties indicates model property that contains the continuation information for the next page.
    @nextPageOperation operations indicates operation that will be called for subsequent page requests.
    @lroStatus enums and model properties indicates model or model property that represents long-running operation status.
    @lroSucceeded enum members indicates enum member that corresponds to the long-running operation succeeded status.
    @lroCanceled enum members indicates enum member that corresponds to the long-running operation canceled status.
    @lroFailed enum members indicates enum member that corresponds to the long-running operation failed status.
    @pollingLocation model properties indicates model property that contains the location to poll for operation state.
    @finalLocation model properties indicates model property that contains the final location for the operation result.
    @operationLink operations indicates operation that is linked to the decorated operation by virtue of its linkType.
    @pollingOperation operations indicates an operation is a polling operation for a long-running operation.
    @finalOperation operations indicates an operation is the final operation for a long-running operation.
    @client client targets indicates the target belongs in a specific client definition.
    @clientDefinition enum members indicates an enum member which contains client description details including any parameters it accepts.

    API

    The @azure-tools/cadl-azure-core library defines the following API functions that emitter authors can use for development:

    Name Entity Returns Description
    getPagedResult models and operations PagedResultMetadata? Returns the PagedResultMetadata if associated with a model or operation return type.
    getItems model properties boolean Returns true if the model property is annotated with @items.
    getNextLink model properties boolean Returns true if the model property is annotated with @nextLink.
    getLongRunningStates enums, models and model properties LongRunningStates? Returns the LongRunningStates associated with an entity.
    isLroSucceededState enum members boolean Returns true if the enum member represents a "succeeded" state.
    isLroCanceledState enum members boolean Returns true if the enum member represents a "canceled" state.
    isLroFailedState enum members boolean Returns true if the enum member represents a "failed" state.
    isPollingLocation model properties boolean Returns true if the model property is annotated with @pollingLocation.
    isFinalLocation model properties boolean Returns true if the model property is annotated with @finalLocation.
    getOperationLink operations OperationLinkMetadata? Returns the OperationLinkMetadata for an operation with a specific linkType.
    getOperationLinks operations Map<string, OperationLinkMetadata>? Returns a Map of OperationLinkMetadata objects for an Operation where the key is the linkType.
    getClientItems enum members ClientTargets[] Returns the array of ClientTargets for a given client definition.
    getClientOperations enum members OperationType[] Returns the array of OperationType for a given client definition.
    getClientDefinition enum members ClientDefinition? Returns the ClientDefinition for a given client enum.
    getClientDefinitions ClientDefinition[] Returns an array of all ClientDefinition in the Cadl spec.
    getReturnedSubclient operations ClientDefinition? Returns the ClientDefinition for a Subclient<TSubclient> operation.

    Generating an OpenAPI Specification

    To generate an OpenAPI v2 (Swagger) specification from the service definition, run the following command inside of the project folder:

    cadl compile . --emit @azure-tools/cadl-autorest
    

    This will create a file in the cadl-output subfolder called openapi.json.

    You can learn more about the cadl-autorest emitter and its options by reading its README.md.

    A Complete Example

    Here's a complete example main.cadl file based on all of the snippets in this README:

    import "@cadl-lang/rest";
    import "@azure-tools/cadl-autorest";
    import "@azure-tools/cadl-azure-core";
    
    @serviceTitle("Contoso Widget Service")
    @serviceVersion("2020-10-01-preview")
    namespace Contoso.Widget;
    
    using Cadl.Http;
    using Cadl.Rest;
    using Azure.Core;
    
    enum Clients {
      WidgetClient,
      PartsClient,
    }
    
    @doc("A Widget resource.")
    @resource("widgets")
    model Widget {
      @key id: string;
      name: string;
    }
    
    @client(Clients.WidgetClient)
    interface Widgets {
      @doc("Get the details of a widget.")
      get is ResourceRead<Widget>;
    
      @doc("Creates a new widget or replaces an existing one.")
      create is LongRunningResourceCreateOrReplace<Widget>;
    
      @doc("Deletes a widget.")
      delete is LongRunningResourceDelete<Widget>;
    
      @doc("Lists the existing widgets.")
      list is ResourceList<Widget>;
    
      @doc("Processes all available widgets.")
      @collectionAction(Widget, "process")
      process is ResourceCollectionAction<
        Widget,
        ProcessWidgetParams,
        Foundations.AcceptedResponse & Foundations.LongRunningStatusLocation
      >;
    
      @doc("Returns a PartsClient object.")
      getPartsClient is Subclient<Clients.PartsClient>;
    }
    
    @doc("A WidgetPart resource belonging to a Widget resource.")
    @resource("parts")
    @parentResource(Widget)
    model WidgetPart {
      @key("partName")
      name: string;
    }
    
    @doc("The properties of WidgetPart")
    model WidgetPartProperties {
      @doc("The part number.")
      number: string;
    
      @doc("The part name.")
      partName: string;
    }
    
    @client(Clients.PartsClient)
    interface WidgetParts {
      @doc("Lists all parts of a widget.")
      listParts is NonPagedResourceList<WidgetPart>;
    
      @doc("Gets the metadata description of a widget part.")
      getPart is ResourceRead<WidgetPart>;
    }
    

    Keywords

    Install

    npm i @azure-tools/cadl-azure-core

    DownloadsWeekly Downloads

    1,772

    Version

    0.7.0

    License

    MIT

    Unpacked Size

    130 kB

    Total Files

    27

    Last publish

    Collaborators

    • azure-sdk