2.2.3.1 URI Syntax

The Augmented BNF for URI Construction listing in this section specifies that a data service URI (see dataSvcAbs-URI) is comprised of four sections: the scheme [RFC3986], a data service root or path prefix, a resource path, and query options, which, when composed, form an absolute URI to address any EntitySet, EntityType instance, property, or service operation result in an Entity Data Model (EDM).

Servers that conform to this specification MAY follow the grammar below when constructing the scheme, service root, and resource path URI components of a data service URI. All servers MUST follow these grammar rules when constructing and parsing the query options section of a data service URI.

 dataSvcAbs-URI      = scheme           ; see section 3.1 of [RFC3986]
                       host             ; section 3.2.2 of [RFC3986]
                       [ ":" port ]     ; section 3.2.3 of [RFC3986]                         
                       (serviceRoot ["/$metadata" / "/$batch"]) ; see section 2.2.3.2
                       / (pathPrefix [dataSvcRel-URI])
  
 dataSvcAbsNqo-URI   = scheme
                       ; see section 3.1 of [RFC3986]
                       serviceRoot           ; see section 2.2.3.2
                       [resourcePath]
  
 dataSvcRel-URI      = resourcePath ["?" queryOptions ]   ; see section 2.2.3.3
  
 serviceRoot         = 
                       *( "/" segment-nz ) ; section 3.3 of [RFC3986]
                          ; segment-nz = the non empty sequence of characters
                          ;              outside the set of URI reserved
                          ;              characters as specified in [RFC3986]
  
 pathPrefix          = *( "/" segment-nz )
                       ; zero or more URI path segments 
  
 resourcePath        = "/"
                       ( 
                         ( 
                           [entityContainer "."] entitySet
                           / serviceOperation-collEt
                           
                         )
                         [ paren ] ["/" namespaceQualifiedEntityType] [ navPath ] [ count ] 
                       )
                       / functionCall ["/" namespaceQualifiedEntityType] [ navPath ] [ count ]
                       / serviceOperation ["/" namespaceQualifiedEntityType]
                       / actionCall
  
 paren               = "()"
  
 serviceOperation    = serviceOperation-et
                       / serviceOperation-collCt
                       / serviceOperation-ct
                       / serviceOperation-collPrim
                       / serviceOperation-prim [ value ]
                       / serviceOperation-void
  
 count               = "/$count" 
      ; count is supported only in OData 2.0 and OData 3.0
  
 navPath             = ( "("keyPredicate")"  [navPath-options] ) / 
                       operation
                         
 operation           = "/" 
                       ( actionCall /
                         (functionCall-partiallyBound [navPath-options])
                       )
      ; operation segments can only be composed if the type of theprevious segment matches 
      ; the type of the first parameter of the action or function being called.
                        
 actionCall          = actionFQName "()"
                       ; TODO: parameters to actions are provided in the BODY
                       ; TOOD: we are considering allowing some parameters in the URL
  
 actionFQName        = [ entityContainer "." ] actionName
  
 actionName         = ; section 2.2.1.3.1
                    ; name of an Action defined by a FunctionImport in the EDM model 
                    ; associated with this data service.
  
  
 functionFQName      = [ entityContainer "." ] functionName
  
 functionName        = ; section 2.2.1.4.1
                    ; name of a function defined by a FunctionImport in the EDM model 
                    ; associated with this data service.
  
 functionCall        = functionFQName "(" [functionParameters] ")"
                    ; if this function call is the last function call in the path,
                    ; from left to right, then the parameters MAY be provided in the query
                    ; part of the URI, without using parameterAlias(es) but instead using the
                    ; names of the FunctionImport parameters, as per serviceOperations.
  
 functionParameters  = ( functionParameter *( "," functionParameter ) ) 
  
 functionParameter   = functionParameterName "=" primitiveValue / functionParameterAlias / null
  
 functionParameterName = *pchar     
                    ; the name of the parameter as found in the corresponding FunctionImport 
                    ; definition.
  
 functionCall-partiallyBound = functionFQName "(" [functionParameters-unbound] ")"
  
 functionParameters-unbound  = functionParameter-unbound *( "," functionParameter-unbound )
                    ; if this function call is the last function call in the path,
                    ; from left to right, then the parameters MAY be provided in the query
                    ; part of the URI, as per serviceOperation(s), except the bound parameter
                    ; which is specified in the path prefix to the function call.
  
 functionParameter-unbound = functionParameter 
                       ; with the added restriction that the parameter must not be a 
                       ; binding parameter
                       
 functionParameterAlias      = @ *pchar     ; i.e. @parameterName
  
 navPath-options     = [
                         navPath-np / 
                         propertyPath / 
                         propertyPath-ct / 
                         namedStreamPath / 
                         value /
                         operation 
                        ]
  
 navPath-np          = ["/"namespaceQualifiedEntityType] "/"
                       ( ("$links" / entityNavProperty )
                         / (entityNavProperty-es [ paren ] [ navPath ])
                         / (entityNavProperty-et [ navPath-options ]))
  
 entityNavProperty = (entityNavProperty-es [ paren ])
                       / entityNavProperty-et
  
 propertyPath        = ["/"namespaceQualifiedEntityType]"/" (entityProperty [value]) / entityCollectionProperty
  
 propertyPath-ct     = 1*(["/" namespaceQualifiedEntityType]"/" entityComplexProperty) [ propertyPath ]
  
 namedStreamPath     = ["/" namespaceQualifiedEntityType]"/" entityNamedStream
 ; the namedStreamPath is supported only in OData 3.0
 keyPredicate        = keyPredicate-single
                       / keyPredicate-cmplx
  
 keyPredicate-single = primitiveValue
  
 primitiveValue      = 1*DIGIT                                 ; section B.1 of [RFC5234]
                       / ([1*unreserved] "’" 1*unreserved "’") ; section 2.3 of [RFC3986]
                       / 1*(HEXDIG HEXDIG))                    ; section B.1 of [RFC5234]
  
 namespaceQualifiedType = namespaceQualifiedComplexType | 
            namespaceQualifiedEntityType | 
            primitiveType | 
            "Collection(" namespaceQualifiedEntityType ")" | 
            "Collection(" 
                ( namespaceQualifiedComplexType | primitiveType )
            ")"
  
 namespaceQualifiedEntityType  = namespace "." entityType
     ; the namespaceQualifiedEntityType is supported only in OData 3.0
  
 namespaceQualifiedComplexType = namespace "." complexType
  
 namespace = *pchar   ; section 3.3 of [RFC3986]
      ; the Namespace of the schema of the EDM model where an EntityType(s),
      ; ComplexType(s) or PrimitiveType(s) is defined.
 primitiveType = [ "Edm." ] primitiveTypeName
   null = "null" [ "'" namespaceQualifiedType "'" ] 
          ; the optional namespaceQualifiedType is used to specify what type this 
          ; null value should be considered for function overload resolution purposes. 
 primitiveTypeName = "binary" |
                     "boolean" |
                     "byte" |
                     "datetime" |
                     "decimal" |
                     "double" |
                     "single" |
                     "float" |
                     "guid" |
                     "int16" |
                     "int32" |
                     "int64" |
                     "sbyte" |
                     "string" |
                     "time" |
                     "datetimeoffset" |
                     "stream" |
                     concreteSpatialTypeName |
                     abstractSpatialTypeName
  
  
 concreteSpatialTypeName  = "point" |
                        "linestring" |
                        "polygon" |
                        "geographycollection" |
                        "multipoint" |
                        "multilinedtring" |
                        "multipolygon" |
                        "geometricpoint" |
                        "geometriclinestring" |
                        "geometricpolygon" |
                        "geometrycollection" |
                        "geometricmultipoint" |
                        "geometricmultilinestring" |
                        "geometricmultipolygon" |
  
 abstractSpatialTypeName  = "geography" |
                            "geometry" |                    
  
 keyPredicate-cmplx  = entityProperty "=" keyPredicate-single
                       ["," keyPredicate-cmplx]
  
 value               = "/$value"
  
 queryOptions = sysQueryOption        ; see section 2.2.3.6.1
               / customQueryOption   ; section 2.2.3.6.2
               / serviceOpParam      ; see section 2.2.3.6.3
               / functionParameter       ; see section 2.2.3.6.4
              *("&"(sysQueryOption / serviceOpParam
              / customQueryOption / functionParameter))
  
 sysQueryOption    = expandQueryOp
                   / filterQueryOp
                   / orderbyQueryOp
                   / skipQueryOp
                   / topQueryOp
                   / formatQueryOp
                   / countQueryOp
                   / selectQueryOp
                   / skiptokenQueryOpcustomQueryOption   = *pchar        ; section 3.3 of [RFC3986]
  
 expandQueryOp       = ; see section 2.2.3.6.1.3
  
 filterQueryOp       = ; see section 2.2.3.6.1.4
  
 orderbyQueryOp      = ; see section 2.2.3.6.1.6
  
 skipQueryOp         = ; see section 2.2.3.6.1.7
  
 serviceOpArg        = ; see section 2.2.3.6.3
  
 topQueryOp          = ; see section 2.2.3.6.1.8   
  
 formatQueryOp       = ; see section 2.2.3.6.1.5
  
 countQueryOp        = ; see section 2.2.3.6.1.10
      ; the countQueryOp is supported only in OData 2.0 and OData 3.0
  
 selectQueryOp       = ; see section 2.2.3.6.1.11
  
 skiptokenQueryOp    = ; see section 2.2.3.6.1.9
  
 ;Note: The semantic meaning, relationship to Entity Data Model
 ;      (EDM) constructs and additional URI construction
 ;      constraints for the following grammar rules are further
 ;      defined in (section 2.2.3.4) and (section 2.2.3.5)
  
 ; See [MC-CSDL] for further scoping rules regarding the value
 ;      of each of the rules below
  
 entityContainer     = ; section 2.2.1.3.1
      ; the name of an Entity Container in the EDM model
  
 entitySet           = *pchar   ; section 3.3 of [RFC3986]
      ; the name of an Entity Set in the EDM model
  
 entityType          = *pchar   ; section 3.3 of [RFC3986]
      ; the name of an Entity Type in the EDM model
  
 complexType          = *pchar   ; section 3.3 of [RFC3986]
      ; the name of an Complex Type in the EDM model
  
 entityProperty      = *pchar   ; section 3.3 of [RFC3986]
      ; the name of a property (of type EDMSimpleType) on an
      ; Entity Type in the EDM 
      ; model associated with the data service
  
 entityComplexProperty   = *pchar   ; section 3.3 of [RFC3986]
      ; the name of a property (of type ComplexType) on an
      ; Entity Type in the EDM 
      ; model associated with the data service
  
 entityCollectionProperty   = *pchar   ; section 3.3 of [RFC3986]
      ; the entityCollectionProperty is supported only in OData 3.0
      ; the name of a property (of type Collection) on an
      ; Entity Type in the EDM 
      ; model associated with the data service
  
 entityNavProperty-es= *pchar   ; section 3.3 of [RFC3986]
      ; the name of a Navigation Property on an Entity Type in
      ; the EDM model associated with the data service.  The
      ; Navigation Property MUST identify an Entity Set.  
  
 entityNavProperty-et= *pchar   ; section 3.3 of [RFC3986]
      ; the name of a Navigation Property on an Entity Type
      ; in the EDM model associated with the data service.
      ; The Navigation Property MUST identify  an entity.  
  
 entityNamedStream   = *pchar       ; section 3.3 of [RFC3986]
      ; the entityNamedStream is supported only in OData 3.0
      ; the name of a Named Resource Stream on an Entity Type 
      ; in the EDM model associated with the data service.
  
 serviceOperation-collEt = *pchar   ; section 3.3 of [RFC3986]
      ; the name of a Function Import in the EDM model which returns a
      ; collection of entities from the same Entity Set
  
 serviceOperation-et = *pchar       ; section 3.3 of [RFC3986]
      ; the name of a Function Import which returns a single Entity
      ; Type instance
  
 serviceOperation-collCt = *pchar   ; section 3.3 of [RFC3986]
      ; the name of a Function Import which returns a collection of
      ; Complex Type [MC-CSDL] instances.  Each member of the
      ; collection is of the same type.
  
 serviceOperation-ct = *pchar       ; section 3.3 of [RFC3986]
      ; the name of a Function Import which returns a single 
      ; Complex Type [MC-CSDL] instance.  
  
 serviceOperation-collPrim = *pchar ; section 3.3 of [RFC3986]
      ; the name of a Function Import which returns a collection
      ; of primitive type (see section 2.2.2) values.  Each member
      ; of the collection is of the same type.  
  
 serviceOperation-prim = *pchar     ; section 3.3 of [RFC3986]
      ; the name of a Function Import which returns a single primitive
      ; type (see section 2.2.2) value. 
  
 serviceOperation-void = *pchar      ; section 3.3 of [RFC39876]
      ; the name of a Function Import that has no ReturnType.

Listing: Augmented BNF for URI Construction