Create and use Custom APIs in Power Apps

Create and use Custom APIs

[This topic is pre-release documentation and is subject to change.]

Custom APIs offer a new code-first way to define messages that you can add to Dataverse web services. Conceptually, Custom APIs are an extension to Custom Actions that have provided a no-code way to include custom messages. To differentiate between the two different kinds of Custom Action, we will use Workflow Custom Action to refer to the no-code capabilities that depend on workflow. Custom API will refer to the type of custom action that depends on a developer to write a plug-in.

Custom APIs provide a capabilities specifically for developers to define their logic in code. For a full comparison of Workflow Custom Action and Custom API, see Compare Workflow Custom Action and Custom API.

Create a custom API

Because a Custom API requires a plug-in to implement any logic to be defined by the main operation, you can approach the development of your custom API by:

  • Write the plug-in first, and then define the Custom API for it.
  • Define the Custom API first, then write the plug-in to implement it.

Your Custom API will be completed when the data defining the Custom API is saved and linked to the Plug-in type to define the main operation. In either case, you should understand the data that drives the Custom API.

There are several different ways to create a custom API:

 Note

Although Custom API data is stored in entities, we do not support creating a model-driven app for these entities. A designer is planned for a future release.

Regardless of the process you use, the following information describes selected attributes for the three entities that contain the data for a Custom API. You should review this as you plan the behavior for your Custom API.

CustomAPI entity attributes

This table includes attributes of the Custom API entity that you can set.

 
Display Name
Schema Name
TypeDescription
Allowed Custom Processing Step Type
AllowedCustomProcessingStepType
Picklist The type of custom processing steps allowed for this Custom API. This allows you to control whether other plug-ins can be registered
  • Value: 0 Label: None Meaning: No custom processing steps allowed.
  • Value: 1 Label: Async Only Meaning: Only asynchronous custom processing steps allowed
  • Value: 2 Label: Sync and Async Meaning: No restriction. 3rd party plug-ins can add synchronous logic to change the behavior of the message.
Cannot be changed after it is saved.
Binding Type
BindingType
Picklist The binding type of the custom API.
  • Value: 0 Label: Global
  • Value: 1 Label: Entity
  • Value: 2 Label: EntityCollection
Cannot be changed after it is saved.
Bound Entity Logical Name
BoundEntityLogicalName
String The logical name of the entity bound to the custom API if it is not Global.
Cannot be changed after it is saved.
Custom API
CustomAPIId
Uniqueidentifier Unique identifier for custom API instances
Cannot be changed after it is saved.
Description
Description
String Localized description for this Custom API. For use when the message is exposed to be called in an app. For example, as a ToolTip.
Display Name
DisplayName
String Localized display name for this Custom API. For use when the message is exposed to be called in an app.
Execute Privilege Name
ExecutePrivilegeName
String (Optional) Name of the privilege that allows execution of the custom API
Is Function
IsFunction
Boolean Indicates if the custom API is a function. A function requires the HTTP GET method. Otherwise the Http POST method is required.
  • Value: 0 Label: No
  • Value: 1 Label: Yes
Important: A function MUST include at least one Response Property to be valid.
More information: Use Web API functions
Cannot be changed after it is saved.
Is Private
IsPrivate
Boolean Indicates if the custom API is private (hidden from metadata and documentation) More information: Private Messages
  • Value: 0 Label: No 
  • Value: 1 Label: Yes
Name
Name
String The primary name of the custom API. This will display in the list of custom apis when viewed in the solution.
Owner
OwnerId
Owner A reference to the user or team that owns the API.
Plugin Type
PluginTypeId
Lookup A reference to the plug-in type that provides the main operation for this Custom API
Unique Name
UniqueName
String Unique name for the custom API. This will be the name of the message created.
This value must include a customization prefix that matches the prefix set for your solution publisher.
Cannot be changed after it is saved.

 Note

Some values are not valid for update. They cannot be changed after the Custom API is saved. You should have a clear understanding of how your API should work before you begin. If you need to change any values that are not valid for update, you will have to delete the Custom API entity record and start over. Deleting the Custom API record will delete any Custom API Request Parameters or Custom API Response Properties associated with it.

Set the Execute Privilege Name property to the name of the privilege to require it. There is currently no supported way for developers outside of Microsoft to create new privileges, but an existing privilege can be used. More information: Q: Can I create a new privilege for my Custom API?

If you do not set the Plugin Type (PluginTypeId) to specify main operation logic the API can still be called. You might want to do this as a testing step, but any output parameter values will return the default values for the type because there is no code to set them.

Known Issues:

CustomAPIRequestParameter entity attributes

A custom API isn’t required to have any parameters. There is no specified order for the parameters, they are identified by name.

A parameter is related to a single Custom API. You cannot define multiple Custom APIs to use the same parameter definition. You can define multiple request parameter with the same UniqueName value if they are used by different Custom APIs.

 Note

If you define a bound entity or entity collection for your Custom API, the parameter will be generated for you. You don’t need to create a parameter for bound entities.

This table includes attributes of the Custom API Request Parameter entity that you can set.

 
Display Name
Schema Name
TypeDescription
Custom API Request Parameter
CustomAPIRequestParameterId
Uniqueidentifier Unique identifier for custom API request parameter instances.
Cannot be changed after it is saved.
Custom API 
CustomAPIId
Lookup Unique identifier for the custom API that this custom API request parameter is associated with.
Cannot be changed after it is saved.
Description
Description
String Localized description for custom API request parameter instances. For use when the message parameter is exposed to be called in an app. For example, as a ToolTip.
Display Name 
DisplayName
String Localized display name for custom API request parameter instances. For use when the message parameter is exposed to be called in an app.
Is Optional
IsOptional
Boolean Indicates if the custom API request parameter is optional. If it is not optional, it is required to pass a value for this parameter when using the message.
  • Value: 0 Label: No 
  • Value: 1 Label: Yes
Cannot be changed after it is saved.
Logical Entity Name
LogicalEntityName
String The logical name of the entity bound to the custom API request parameter.
Cannot be changed after it is saved.
Name
Name
String The primary name of the custom API request parameter. This will display in the list of custom api request parameters when viewed in the solution. Use this to differentiate this parameter from others that share a common Unique Name. 
This naming convention is recommended: {Custom API Unique Name}.{Parameter UniqueName}
Owner 
OwnerId
Owner A reference to the user or team that owns the API.
Type
Type
Picklist The data type of the custom API request parameter.
  • Value: 0 Label: Boolean 
  • Value: 1 Label: DateTime
  • Value: 2 Label: Decimal 
  • Value: 3 Label: Entity
  • Value: 4 Label: EntityCollection 
  • Value: 5 Label: EntityReference
  • Value: 6 Label: Float 
  • Value: 7 Label: Integer
  • Value: 8 Label: Money 
  • Value: 9 Label: Picklist
  • Value: 10 Label: String 
  • Value: 11 Label: StringArray 
  • Value: 12 Label: Guid 
Cannot be changed after it is saved.
Unique Name 
UniqueName
String Unique name for the custom API request parameter. This will be the name of the parameter when you call the Custom API.
Cannot be changed after it is saved.

 Note

Some values are not valid for update. They cannot be changed after the Custom API Request Parameter is saved. If you need to change one of these values, you must delete the Custom API Request Parameter and re-create it with the changes you want to make.

CustomAPIResponseProperty entity attributes

The object returned for your Custom API message will include any response properties you define. It is not required for a Custom API to return any value, but if the custom API is defined as a function it is required.

 Important

A Custom API that represents a function with no response properties is not valid and will not appear in the Web API $metadata service document. If you try to use it, you will get a 404 Not Found error similar to this:

{"error":{"code":"0x8006088a","message":"Resource not found for the segment 'your_function_name'."}}.

You must also set the data to be returned in the plug-in for the function. If no data is set to be returned by the plug-in, the operation will return 204 No Content.

If there is only a single Entity or EntityCollection response property defined, the response will be of that type. If there are multiple parameters, or one or more parameter of a simple type, the API will return a complex type where each response property will be a property of that complex type. For example, if your Custom API Unique name is sample_CustomAPIExample, it will return a complex type named sample_CustomAPIExampleResponse with properties for each response property you define.

This table includes attributes of the Custom API Response Property entity that you can set.

 
Display Name
Schema Name
TypeDescription
Custom API Response Property
CustomAPIResponsePropertyId
Uniqueidentifier Unique identifier for custom API response property instances.
Cannot be changed after it is saved.
Custom API 
CustomAPIId
Lookup Unique identifier for the custom API that this custom API response property is associated with. 
Cannot be changed after it is saved.
Description
Description
String Localized description for custom API response property instances. For use when the message parameter is exposed to be called in an app. For example, as a ToolTip.
Display Name 
DisplayName
String Localized display name for custom API response property instances. For use when the message parameter is exposed to be called in an app.
Logical Entity Name
LogicalEntityName
String The logical name of the entity bound to the custom API response property .
Cannot be changed after it is saved.
Name
Name
String The primary name of the custom API response property . This will display in the list of custom api request parameters when viewed in the solution. Use this to differentiate this parameter from others that share a common Unique Name. 
This naming convention is recommended: {Custom API Unique Name}.{Property UniqueName}
Owner 
OwnerId
Owner A reference to the user or team that owns the API.
Type
Type
Picklist The data type of the custom API response property 
  • Value: 0 Label: Boolean 
  • Value: 1 Label: DateTime
  • Value: 2 Label: Decimal 
  • Value: 3 Label: Entity
  • Value: 4 Label: EntityCollection 
  • Value: 5 Label: EntityReference
  • Value: 6 Label: Float 
  • Value: 7 Label: Integer
  • Value: 8 Label: Money 
  • Value: 9 Label: Picklist
  • Value: 10 Label: String 
  • Value: 11 Label: StringArray 
  • Value: 12 Label: Guid 
Cannot be changed after it is saved.
Unique Name 
UniqueName
String Unique name for the custom API response property . This will be the name of the parameter when you call the Custom API.
Cannot be changed after it is saved.

 Note

Some values are not valid for update. They cannot be changed after the Custom API Response Property is saved. If you need to change one of these values, you must delete the Custom API Response Property and re-create it with the changes you want to make.

Invoking Custom APIs

A Custom API creates a new message which can be invoked via the SDK or Web API.

Invoking Custom APIs from SDK based applications or plug-ins

You can choose to use either early-bound or late-bound code to invoke your custom API. Use the CrmSvcUtil tool to generate helper request and response classes to mirror the request and response properties of your custom API.

For late-bound code, create an OrganizationRequest with the unique name of your custom API and add parameters with names matching the unique names of the request properties.

Entity-bound custom APIs have an implicit request property named Target that should be set to an EntityReference of the record to invoke the API on.

You can access response properties from the parameters of the returned response.

C#
var req = new OrganizationRequest("myapi_EscalateCase")
{
  ["Target"] = new EntityReference("incident", guid),
  ["Priority"] = new OptionSetValue(1)
};

var resp = svc.Execute(req);

var newOwner = (EntityReference) resp["AssignedTo"];

Invoking Custom APIs from the Web API

Custom APIs can be called in the same way as any standard Web API functions or actions. If your custom API has the IsFunction field set to true then it needs to be invoked as a function using a GET request, otherwise it needs to be used as an action using a POST request:

HTTP
POST [Organization URI]/api/data/v9.1/myapi_CustomUnboundAPI
OData-MaxVersion: 4.0
OData-Version: 4.0
Content-Type: application/json; charset=utf-8

{
  "InputParameter": "Value"
}
HTTP
GET [Organization URI]/api/v9.1/accounts(ed5d4e42-850c-45b7-8b38-2677545107cc)/Microsoft.Dynamics.CRM.myapi_CustomBoundAPI()
OData-MaxVersion: 4.0
OData-Version: 4.0
Content-Type: application/json; charset=utf-8
HTTP
GET [Organization URI]/api/v9.1/accounts/Microsoft.Dynamics.CRM.myapi_CustomEntityCollectionBoundAPI()
OData-MaxVersion: 4.0
OData-Version: 4.0
Content-Type: application/json; charset=utf-8

Retrieve data about Custom APIs

You can use the following queries to retrieve data about Custom APIs.

Web API

More information: Query Data using the Web API

HTTP
GET [Organization URI]/api/data/v9.1/customapis?$select=
    uniquename,
    allowedcustomprocessingsteptype,
    bindingtype,
    boundentitylogicalname,
    description,
    displayname,
    executeprivilegename,
    isfunction,
    isprivate
  &$expand=
  CustomAPIRequestParameters($select=
    uniquename,
    name,
    description,
    displayname,
    type,
    logicalentityname,
    isoptional),
  CustomAPIResponseProperties($select=
    uniquename,
    name,
    description,
    displayname,
    type,
    logicalentityname),
  PluginTypeId($select=
    plugintypeid,
    typename,
    version,
    name,
    assemblyname)

FetchXml

More information: Use FetchXML to construct a query

XML
<fetch>
  <entity name='customapi' >
    <attribute name='isprivate' />
    <attribute name='description' />
    <attribute name='displayname' />
    <attribute name='executeprivilegename' />
    <attribute name='isfunction' />
    <attribute name='allowedcustomprocessingsteptype' />
    <attribute name='boundentitylogicalname' />
    <attribute name='bindingtype' />
    <attribute name='uniquename' />
    <link-entity name='customapirequestparameter' from='customapiid' to='customapiid' link-type='outer' alias='req' >
      <attribute name='description' />
      <attribute name='displayname' />
      <attribute name='logicalentityname' />
      <attribute name='name' />
      <attribute name='uniquename' />
      <attribute name='type' />
      <attribute name='isoptional' />
    </link-entity>
    <link-entity name='customapiresponseproperty' from='customapiid' to='customapiid' link-type='outer' >
      <attribute name='description' />
      <attribute name='displayname' />
      <attribute name='logicalentityname' />
      <attribute name='name' />
      <attribute name='uniquename' />
      <attribute name='type' />
    </link-entity>
    <link-entity name='plugintype' from='plugintypeid' to='plugintypeid' link-type='outer' alias='plugintype' >
      <attribute name='name' />
      <attribute name='assemblyname' />
      <attribute name='version' />
      <attribute name='plugintypeid' />
      <attribute name='typename' />
    </link-entity>
  </entity>
</fetch>

Using SQL

More information: Use SQL to query data (Preview)

SQL
SELECT api.customapiid,
       api.uniquename,
       api.allowedcustomprocessingsteptype,
       api.bindingtype,
       api.boundentitylogicalname,
       api.description,
       api.displayname,
       api.executeprivilegename,
       api.isfunction,
       api.isprivate,
       req.customapirequestparameterid,
       req.uniquename,
       req.name,
       req.description,
       req.displayname,
       req.type,
       req.logicalentityname,
       req.isoptional,
       resp.customapiresponsepropertyid,
       resp.uniquename,
       resp.name,
       resp.description,
       resp.type,
       resp.logicalentityname,
       type.plugintypeid,
       type.typename,
       type.version,
       type.name,
       type.assemblyname
FROM   customapi AS api
       LEFT JOIN
       customapirequestparameter AS req
       ON api.customapiid = req.customapiid
       LEFT JOIN
       customapiresponseproperty AS resp
       ON api.customapiid = resp.customapiid
       LEFT JOIN
       plugintype AS type
       ON api.plugintypeid = type.plugintypeid

Localized values

You can localize the values using the steps documented here: Translate localizable text for model-driven apps and Translating labels and display strings.

This process involves exporting a file that contains the base language values and will include a column for each additional language enabled. You can then edit the values in Excel. After you complete the process to import the translations the labels will be included in your solution.

The following example shows editing the Excel worksheet to add Japanese translations for the English values.

Shows how labels are localized

 Tip

If you are editing the solution files to create your Custom APIs, you can provide the localized labels directly. More information: Providing Localized Labels with the solution

Setting localized values

If you prefer to set localized labels in code rather than using the manual process described above, you can use the SetLocLabels message using either the Web API SetLocLabels Action or the Organization Service SetLocLabelsRequest.

The following example shows how to use the Web API to set the localized labels for the displayname property of a custom API.

Request

HTTP
POST [Organization URI]/api/data/v9.1/SetLocLabels HTTP/1.1
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
Content-Type: application/json

{
    "EntityMoniker": {
        "@odata.type": "Microsoft.Dynamics.CRM.customapi",
        "customapiid": "86bcd12e-2f30-eb11-a813-000d3a122b89"
    },
    "AttributeName": "displayname",
    "Labels": [
        {
            "Label": "例え",
            "LanguageCode": 1041
        },
        {
            "Label": "Beispiel",
            "LanguageCode": 1031
        },
        {
            "Label": "ejemplo",
            "LanguageCode": 1034
        }
    ]
}

Response

HTTP
HTTP/1.1 204 No Content

Retrieving localized values

To retrieve the localized labels use the RetrieveLocLabels message using either the Web API RetrieveLocLabels Function or the Organization Service RetrieveLocLabelsRequest.

The following example shows using the RetrieveLocLabels Function to retrieve the labels for the the displaynameproperty of a Custom API with the customapiid of 88602189-183d-4584-ba4b-8b60f0f5b89f

Request

HTTP
GET [Organization URI]/api/data/v9.1/RetrieveLocLabels(EntityMoniker=@p1,AttributeName=@p2,IncludeUnpublished=@p3)?
@p1={'@odata.id':'customapis(88602189-183d-4584-ba4b-8b60f0f5b89f)'}&
@p2='displayname'&
@p3=false HTTP/1.1

Response

HTTP
HTTP/1.1 200 OK
OData-Version: 4.0

{
    "@odata.context": "[Organization URI]/api/data/v9.1/$metadata#Microsoft.Dynamics.CRM.RetrieveLocLabelsResponse",
    "Label": {
        "LocalizedLabels": [
            {
                "Label": "Custom API Example",
                "LanguageCode": 1033,
                "IsManaged": null,
                "MetadataId": null,
                "HasChanged": null
            },
            {
                "Label": "カスタムAPIの例",
                "LanguageCode": 1041,
                "IsManaged": null,
                "MetadataId": null,
                "HasChanged": null
            }
        ],
        "UserLocalizedLabel": {
            "Label": "Custom API Example",
            "LanguageCode": 1033,
            "IsManaged": null,
            "MetadataId": null,
            "HasChanged": null
        }
    }
}

 

原文地址:https://www.cnblogs.com/lingdanglfw/p/14377023.html