{"id":2343,"date":"2007-09-21T12:25:00","date_gmt":"2007-09-21T12:25:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/odatateam\/2007\/09\/21\/uri-format-part-1-addressing-resources-using-uri-path-segments\/"},"modified":"2007-09-21T12:25:00","modified_gmt":"2007-09-21T12:25:00","slug":"uri-format-part-1-addressing-resources-using-uri-path-segments","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/odata\/uri-format-part-1-addressing-resources-using-uri-path-segments\/","title":{"rendered":"URI Format &#8211; Part 1 &#8211; Addressing resources using URI path segments"},"content":{"rendered":"<p><P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Deciding on something that becomes a public interface of a developer-oriented technology is a tricky task. Not only does the resulting design need to be correct and complete, but also there are various aspects that are more around aesthetics and personal preference. The URI format used by Astoria will need to survive both sets of challenges\u2026<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">The Astoria REST \u201cprotocol\u201d is made up of a URI addressing scheme, HTTP-based interaction model and payload formats (Web3S\/XML,JSON , ATOM\/APP).<SPAN>&nbsp; <\/SPAN>In the interest of staying focused on the URI format, this write-up will only touch on the URI format used by Astoria and leave discussion of the interaction model to a future post.<SPAN>&nbsp; <\/SPAN>See <\/FONT><A href=\"https:\/\/blogs.msdn.com\/astoriateam\/archive\/2007\/09\/09\/design-feedback-requested.aspx\"><FONT face=\"Calibri\" size=\"3\">this post<\/FONT><\/A><FONT face=\"Calibri\" size=\"3\"> for a discussion around payload formats used by Astoria.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">In general, Astoria takes a conceptual model expressed in terms of entities in an EDM schema and surfaces data that follows that model over an HTTP interface, representing entities as resources and associations between entities as links. The URI interface needs to provide a rich yet simple way of addressing those resources.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">The URI format in Astoria has a few specific goals:<\/FONT><\/P>\n<P class=\"MsoListParagraph\"><SPAN><SPAN><FONT face=\"Calibri\" size=\"3\">a)<\/FONT><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><\/SPAN><\/SPAN><FONT size=\"3\"><FONT face=\"Calibri\"><B>Provide a mechanism to point to every resource or member of a resource in the system.<\/B> That is, every piece of data is addressable, and the URI used to address it needs to be derivable from the service metadata which describes the conceptual model of the system<\/FONT><\/FONT><\/P>\n<P class=\"MsoListParagraph\"><SPAN><SPAN><FONT face=\"Calibri\" size=\"3\">b)<\/FONT><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><\/SPAN><\/SPAN><FONT size=\"3\"><FONT face=\"Calibri\"><B>Allow for simple queries to be formulated.<\/B> That is, instead of pointing to a particular resource, allow URIs that express filtered sets of resources satisfying certain criteria<\/FONT><\/FONT><\/P>\n<P class=\"MsoListParagraph\"><SPAN><SPAN><FONT face=\"Calibri\" size=\"3\">c)<\/FONT><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><\/SPAN><\/SPAN><FONT size=\"3\"><FONT face=\"Calibri\"><B>Support manipulating the presentation of results.<\/B> This includes things such as sorting resources, paging over them and expanding related resources.<\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">This \u201cpart I\u201d write up focuses on item a) above; pointing to resources and their members. We will discuss b) and c) in future blog posts<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">NOTE: the following descriptions use EDM terminology and constructs.<SPAN>&nbsp; <\/SPAN>Regardless of the underlying data access layer (Entity Framework, Custom LINQ provider, etc) an Astoria service is exposing, the service is described using an EDM schema, so this description applies equally to any data source.<SPAN>&nbsp; <\/SPAN>In addition, typical REST verbiage (as is done above) refers to items pointed to by URIs as resources.<SPAN>&nbsp; <\/SPAN>In the remainder of this write up the term \u2018entity\u2019 should be interpreted as a synonym for \u2018resource\u2019.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><B><FONT size=\"3\"><FONT face=\"Calibri\">Starting from the root<\/FONT><\/FONT><\/B><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">At the root of the service we are thinking of carrying the behavior of the CTP forward and putting all of the <I>resource sets<\/I>, which are simply the list of entity sets we find in the EDM schema. These are addressed by name, separated by a forward-slash (\u201c\/\u201d) from the service root URI. (e.g. \u2026\/northwind.svc\/Customers, where \u201cCustomers\u201d is a resource container).<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">A detail: In an EDM schema an entity set is contained within a single entity container and there may be multiple entity containers in the schema. If that\u2019s the case, to access non-default containers, the names need to be container-qualified (e.g. \u201c\/NorthwindContainer.Customers\u201d). The default one *<B>cannot<\/B>* be qualified, to avoid introducing a redundant way of getting to it.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><B><FONT size=\"3\"><FONT face=\"Calibri\">Pointing to a particular entity<\/FONT><\/FONT><\/B><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Every entity in an EDM schema has a key which consists of one or more of the properties in the entity. An entity key is unique within the containing entity set, so to identify an entity with a URI we need to include at least the entity-set and the key values. <\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<BLOCKQUOTE>\n<P class=\"MsoNormal\"><B><FONT size=\"3\"><FONT face=\"Calibri\">&#8211;Location of keys<\/FONT><\/FONT><\/B><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">The key value could go before or after the question mark. That is, the URI could be built by adding a query parameter after the URI question mark as in:<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">\u2026\/northwind.svc\/Customers?key=23<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Or we could consider the entity-set-plus-value construct part of the URI namespace of the service and write it as<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">\u2026\/northwind.svc\/Customers(23)<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">We prefer the second approach with the entity-sets and keys form a URI namespace and there is no query parameter required.<SPAN>&nbsp; <\/SPAN>One of the reasons for leaning towards the second approach is that it makes it explicit which entity set the key is associated with, especially when the URI path becomes quite long. <\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><B><FONT size=\"3\"><FONT face=\"Calibri\">&#8211;a bit of syntax<\/FONT><\/FONT><\/B><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Now, assuming we go with that approach, there is now the question of the syntax. The May 2007 CTP used values in square-brackets (e.g. \u201c\u2026\/Customers[ALFKI]\u201d). We got \u201cgenerous\u201d feedback saying that square-brackets were a bad choice. <\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">The approach we are currently thinking to take is to attach the key directly after the entity set name and using the \u2018!\u2019 character as the separator (e.g. \u2026\/Customers!23 ).<SPAN>&nbsp; <\/SPAN>That said, as per our last \u201cdesign\u201d posting on formats, we are looking to support the Web3S format.<SPAN>&nbsp; <\/SPAN>Web3S has a more flexible data model in that it allows heterogeneous sets while an Astoria server supports homogenous sets.<SPAN>&nbsp; <\/SPAN>To enable interoperability between any servers implementing Web3S and an Astoria server a URI scheme flexible enough to address heterogeneous sets is required.<SPAN>&nbsp; <\/SPAN><SPAN>&nbsp;&nbsp;<\/SPAN>Therefore, we are thinking to expand on our current approach and allow a \u201cfull\u201d form of URI and a \u201ccompressed\u201d form, where the full form supports heterogeneous sets and the compressed form can be used as a shorthand notation when the set being addressed is on an Astoria server and is thus homogenous.<SPAN>&nbsp; <\/SPAN>For example:<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT size=\"3\"><FONT face=\"Calibri\">\u201cFull\u201d form: \u2026\/Customers\/Customer(123) would identify the instance 123 of type Customer within the Customers set.<SPAN>&nbsp; <\/SPAN><\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT size=\"3\"><FONT face=\"Calibri\">\u201cCompressed\u201d form: \u2026\/Customers!123 would identify the same resource as above in Astoria because the \u2018Customer\u2019 type is implied since Astoria Servers support homogenous sets. <SPAN>&nbsp;&nbsp;<\/SPAN><\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><B><FONT size=\"3\"><FONT face=\"Calibri\">&#8211;composite keys<\/FONT><\/FONT><\/B><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">One option would be to encode name\/value pairs, but that would result in verbose URIs and extra syntax to be invented. We are leaning toward a simple approach: we only use the values, separated by semicolon. The values are listed in the same order as they appear in the metadata document which describes the service.<SPAN>&nbsp; <\/SPAN>Metadata will be the topic of a future post, however, for now it\u2019s enough to say in the typical case the description of a service will be available by making a GET request to \u2026\/$metadata.<SPAN>&nbsp; <\/SPAN><SPAN>&nbsp;<\/SPAN>The following is an example of a URI which contains a composite key:<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">\u2026\/Customers!\u2019ALFKI\u2019,2<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Some folks love this, some hate it. The main concern from folks who hate it is readability: you cannot interpret the URI without the schema. Is that an issue? The alternate option of using name-value pairs is more explicit in this sense. We could have:<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">\u2026\/Customers!CustomerID=&#8217;ALFKI&#8217;,Key=2<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">The single-key case would still not require the name, and given that most cases will be single-key cases, compactness won\u2019t suffer too much. An aspect of this that\u2019s both good and bad is the fact that by using names you can specify the values in different order. That\u2019s \u201chandy\u201d, but it means that these URIs are not useful for comparison as strings when trying to determine identity.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><B><FONT size=\"3\"><FONT face=\"Calibri\">&#8212; literal forms<\/FONT><\/FONT><\/B><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Using just literal values in a composite key doesn\u2019t really work, because now you cannot tell whether that\u2019s a 2-element key or a 1 element key that happens to have a comma in it. So we need to use proper literal forms for the values. We will need that when we want to express query expressions such as filter predicates anyway, so we may as well be consistent and use a single literal form everywhere.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Literals:<\/FONT><\/P>\n<P class=\"MsoListParagraph\"><SPAN><SPAN><FONT size=\"3\">\u00b7<\/FONT><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><\/SPAN><\/SPAN><FONT face=\"Calibri\" size=\"3\">Strings: a string surrounded by single-quotes, (e.g. &#8216;ALFKI&#8217;)<\/FONT><\/P>\n<P class=\"MsoListParagraph\"><SPAN><SPAN><FONT size=\"3\">\u00b7<\/FONT><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><\/SPAN><\/SPAN><FONT face=\"Calibri\" size=\"3\">Numbers: just the number, using US style (dot separates decimal digits)<\/FONT><\/P>\n<P class=\"MsoListParagraph\"><SPAN><SPAN><FONT size=\"3\">\u00b7<\/FONT><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><\/SPAN><\/SPAN><FONT face=\"Calibri\" size=\"3\">Dates: quoted as strings. Inside the string, use format described in RFC3339<\/FONT><\/P>\n<P class=\"MsoListParagraph\"><SPAN><SPAN><FONT size=\"3\">\u00b7<\/FONT><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><\/SPAN><\/SPAN><FONT face=\"Calibri\" size=\"3\">Guids: use the form <\/FONT><SPAN>\u201cdddddddd-dddd-dddd-dddd-dddddddddddd\u201d<\/SPAN><\/P>\n<P class=\"MsoListParagraph\"><SPAN><SPAN><FONT size=\"3\">\u00b7<\/FONT><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><\/SPAN><\/SPAN><FONT face=\"Calibri\" size=\"3\">Binary: \u201c0x\u201d followed by two hex digits per byte (e.g. 0x1AB4)<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">So the examples above would actually be, for single- and composite-key respectively:<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">\u2026\/Customers(&#8216;ALFKI&#8217;)<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">\u2026\/Customers(&#8216;ALFKI&#8217;,2)<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Probably is a good idea to <B>not<\/B> allow spaces, as it would help making sure that URIs that mean the same thing are easily comparable.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P><\/BLOCKQUOTE>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><B><FONT size=\"3\"><FONT face=\"Calibri\">Addressing members<\/FONT><\/FONT><\/B><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">To address a member of an entity, simply append the member to a URI that points to the entity, separated by a forward-slash. For example, if Customers have a CompanyName property:<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">\u2026\/Customers!&#8217;ALFKI&#8217;\/CompanyName<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Note that addressing a member like that would return the member appropriately wrapped to conform to the negotiated MIME type. For example, if using XML you\u2019d get the value wrapped in an XML element and annotated with the required namespaces and such.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">If you want just the value with no wrappers, you can use the \/$value \u201cmagic member\u201d. For example:<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">\u2026\/Customers(&#8216;ALFKI&#8217;)\/CompanyName\/$value<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">For a string, this would just return the string (text\/plain) by default (same applies to all types but binary, which would return application\/octet-stream). The developer can customize this by annotating the schema and indicating which MIME type a given value should be treated as. That would allow for example a text field to store HTML or a binary field to store an image, and HTTP responses would include the proper MIME type for them.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><B><FONT size=\"3\"><FONT face=\"Calibri\">Association traversal<\/FONT><\/FONT><\/B><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">A special form of member access is when the member being accessed is actually a navigation property (a link in non EDM terms). Such a property can be considered a hard-link that resolves into the related entity (for associations that have a cardinality of 1 on the other end) or a set of entities (if the other end is \u201cmany\u201d).<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">The syntax is the same as in regular members, independent of the cardinality of the other end. So, if a customer has sales orders, the URI to access the orders would be:<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">\u2026\/Customers!&#8217;ALFKI&#8217;\/Orders<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><B><FONT size=\"3\"><FONT face=\"Calibri\">Keep drilling down<\/FONT><\/FONT><\/B><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">When the result of a given URI is a single object, the members of those objects can be accessed by adding the member name to the URI. <SPAN>&nbsp;<\/SPAN>For example, if a customer has a \u201cContact\u201d navigation property that points to a single Person object, which has a Name property, the name can be retrieved directly by using this URI:<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">\u2026\/Customers!&#8217;ALFKI&#8217;\/Contact\/Name<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">For the case where traversing an association yields a set, you need to further scope the set by providing a key to point to a single element of the set in order to traverse further using the URI path.<SPAN>&nbsp; <\/SPAN>For example if a customer has a set of orders and each order has an order date property, one valid URI to access an order date would be:<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">\u2026\/Customers!&#8217;ALFKI&#8217;\/Orders!123\/OrderDate<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><B><FONT size=\"3\"><FONT face=\"Calibri\">A note on escaping<\/FONT><\/FONT><\/B><\/P>\n<P class=\"MsoNormal\"><FONT size=\"3\"><FONT face=\"Calibri\">Quite a bit of escaping beyond basic URI encoding is necessary for the whole scheme to work. Things like \u201c=\u201d and \u201c?\u201d need to be carefully handled to not confuse URI translators and agents. Details go beyond this write up, but specific thoughts are welcome. Although the trickiest one deserves to be brought up: should we escape \u201c\/\u201d inside a quoted string? The same question, asked more deeply, is \u201cshould we assume that consumers of Astoria URIs understand their syntax?\u201d.<SPAN>&nbsp; <\/SPAN><\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">In general, we are leaning towards requiring characters of special meaning in a URI path (ex. \u2018\/\u2019) to be escaped even when such a character is within a quoted string.<SPAN>&nbsp; <\/SPAN>If the character is not escaped we will treat it as per its predefined meaning in path segments in RFC 3986.<SPAN>&nbsp; <\/SPAN>We believe this would provide a consistent method for developers to craft and interpret URIs.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P><FONT face=\"Calibri\">\n<P class=\"MsoNormal\"><B><FONT size=\"3\">Wrapping Up&#8230;<\/FONT><\/B><\/P>\n<P class=\"MsoNormal\"><FONT size=\"3\">The ideas presented above represent our current thinking in the space.&nbsp; As always, feedback and comments are most welcome.&nbsp; We look forward to hearing your thoughts.&nbsp;&nbsp; In follow up posts we will discuss the query string section of the URI and dig into addressing service operations.<\/FONT><\/P><\/FONT>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Mike Flasko<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Program Manager<\/FONT><\/P>\n<P class=\"MsoNormal\"><A href=\"http:\/\/blogs.msdn.com\/mflasko\"><FONT face=\"Calibri\" size=\"3\">http:\/\/blogs.msdn.com\/mflasko<\/FONT><\/A><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Pablo Castro<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Tech Lead <\/FONT><\/P>\n<P class=\"MsoNormal\"><A href=\"http:\/\/blogs.msdn.com\/pablo\"><FONT face=\"Calibri\" size=\"3\">http:\/\/blogs.msdn.com\/pablo<\/FONT><\/A><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><SPAN><FONT face=\"Calibri\" size=\"3\">&nbsp; <\/P>\n<P><SPAN lang=\"EN\">This post is part of the transparent design exercise in the Astoria Team. To understand how it works and how your feedback will be used please look at <A href=\"https:\/\/blogs.msdn.com\/astoriateam\/archive\/2007\/07\/20\/transparency-in-the-design-process.aspx\"><FONT color=\"#0000ff\">this post<\/FONT><\/A>.<\/SPAN><\/P><\/FONT><\/SPAN>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Deciding on something that becomes a public interface of a developer-oriented technology is a tricky task. Not only does the resulting design need to be correct and complete, but also there are various aspects that are more around aesthetics and personal preference. The URI format used by Astoria will need to survive both sets of [&hellip;]<\/p>\n","protected":false},"author":512,"featured_media":3253,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[27,61],"class_list":["post-2343","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-odata","tag-design-notes","tag-project-codename-astoria"],"acf":[],"blog_post_summary":"<p>Deciding on something that becomes a public interface of a developer-oriented technology is a tricky task. Not only does the resulting design need to be correct and complete, but also there are various aspects that are more around aesthetics and personal preference. The URI format used by Astoria will need to survive both sets of [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/posts\/2343","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/users\/512"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/comments?post=2343"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/posts\/2343\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/media\/3253"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/media?parent=2343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/categories?post=2343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/tags?post=2343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}