Uploaded image for project: 'OASIS Open Data Protocol (OData) TC'
  1. OASIS Open Data Protocol (OData) TC
  2. ODATA-1428

Definition of service-specific client-side functions

    XMLWordPrintable

    Details

      Description

      According to OData-CSDL, section 14.4.4 services can define client-side functions outside the odata namespace.

      • Can they be defined like server-side functions, through edm:Function? (I think yes, because the client should be able to delegate their execution to the server.)
      • Does edm:Function need an attribute ClientSide="true"? (I think yes, if this means: can¬†only be executed by the client.)
      • Or perhaps a new core annotation (no need to wait for the next CSDL version):
        <Term Name="ClientSideOnly" AppliesTo="Function" Type="Core.Tag" Nullable="false" DefaultValue="true">
         <Annotation Term="Core.Description" String="Client-side function as in [OData-CSDL, section 14.4.4](https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#sec_ApplyClientSideFunction) that cannot be executed by the server"/>
         <Annotation Term="Core.LongDescription" String="A function without this tag can also occur as a client-side function in an apply expression for an annotation. The client can then delegate the execution to the server by `$compute`-ing the function."/>
        </Term>
        

      A function without this tag can occur in an annotation that is contributed by a proxy between OData client and server. Continuing the example from ODATA-1420, assume the proxy contributes the following annotation:

      <Schema Namespace="SalesOrderServer">
       <EntityType Name="SalesOrderItem">
        <Property Name="Pieces" Type="Edm.Int"/>
        <Property Name="Price" Type="Edm.Decimal"/>
        <Annotation Term="PAngV.PriceSection2">
         <Apply Function="SalesOrderServer.PricePerPiece">
          <Path>Price</Path>
          <Path>Pieces</Path>
         </Apply>
        </Annotation>
       </EntityType>
      </Schema>

      The proxy would then convert the request

      GET ~/SalesOrderItems?$select=ItemNo,@PAngV.PriceSection2
      

      into

      GET ~/SalesOrderItems?$select=ItemNo
      &$compute=SalesOrderServer.PricePerPiece(Price=Price,Pieces=Pieces) as PriceSection2
      

      forward the converted request to the SalesOrderServer and rename JSON property PriceSection2 to @PAngV.PriceSection2 in the response, effectively handling the instance annotation @PAngV.PriceSection2 like an additional property.

      This examples assumes that the SalesOrderServer.PricePerPiece function is implemented on the server. If the server declared that function ClientSideOnly, or if the function was contributed by the proxy instead, then the proxy would send the following metadata to the client:

      <Schema Namespace="SalesOrderServer"> <!-- namespace of server -->
       <EntityType Name="SalesOrderItem">
        <Property Name="Pieces" Type="Edm.Int"/>
        <Property Name="Price" Type="Edm.Decimal"/>
        <Annotation Term="PAngV.PriceSection2">
         <Apply Function="PAngV.PricePerPiece">
          <Path>Price</Path>
          <Path>Pieces</Path>
         </Apply>
        </Annotation>
       </EntityType>
      </Schema>
      <Schema Namespace="PAngV"> <!-- namespace of proxy -->
       <Function Name="PricePerPiece">
        <Annotation Term="Core.ClientSideOnly" Bool="false"/>
        ...
       </Function>
      </Schema>
      

      and the proxy would request

      GET ~/SalesOrderItems?$select=ItemNo,Price,Pieces
      

      from the server and perform the computation of @PAngV.PriceSection2 itself.

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              heiko.theissen Heiko Theissen
            • Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated: