> This article describes the routing conventions that Web API uses for OData endpoints.
When Web API gets an OData request, it maps the request to a controller name and an action name. The mapping is based on the HTTP method and the URI. For example, `GET /odata/Products(1)` maps to `ProductsController.GetProduct`.
In part 1 of this article, I describe the built-in OData routing conventions. These conventions are designed specifically for OData endpoints, and they replace the default Web API routing system. (The replacement happens when you call **MapODataRoute**.)
In part 2, I show how to add custom routing conventions. Currently the built-in conventions do not cover the entire range of OData URIs, but you can extend them to handle additional cases.
- [Built-in Routing Conventions](#conventions)
- [Custom Routing Conventions](#custom)
<aid="conventions"></a>
## Built-in Routing Conventions
Before I describe the OData routing conventions in Web API, it's helpful to understand OData URIs. An [OData URI](http://www.odata.org/documentation/odata-v3-documentation/url-conventions/) consists of:
- The service root
- The resource path
- Query options
![](odata-routing-conventions/_static/image1.png)
For routing, the important part is the resource path. The resource path is divided into segments. For example, `/Products(1)/Supplier` has three segments:
-`Products` refers to an entity set named "Products".
-`1` is an entity key, selecting a single entity from the set.
-`Supplier` is a navigation property that selects a related entity.
So this path picks out the supplier of product 1.
> [!NOTE]
> OData path segments do not always correspond to URI segments. For example, "1" is considered a path segment.
**Controller Names.** The controller name is always derived from the entity set at the root of the resource path. For example, if the resource path is `/Products(1)/Supplier`, Web API looks for a controller named `ProductsController`.
**Action Names.** Action names are derived from the path segments plus the entity data model (EDM), as listed in the following tables. In some cases, you have two choices for the action name. For example, "Get" or "GetProducts".
**Querying Entities**
| Request | Example URI | Action Name | Example Action |
| --- | --- | --- | --- |
| GET /entityset | /Products | GetEntitySet or Get | GetProducts |
| GET /entityset(key) | /Products(1) | GetEntityType or Get | GetProduct |
| GET /entityset(key)/cast | /Products(1)/Models.Book | GetEntityType or Get | GetBook |
For more information, see [Create a Read-Only OData Endpoint](odata-v3/creating-an-odata-endpoint.md).
**Creating, Updating, and Deleting Entities**
| Request | Example URI | Action Name | Example Action |
| --- | --- | --- | --- |
| POST /entityset | /Products | PostEntityType or Post | PostProduct |
| PUT /entityset(key) | /Products(1) | PutEntityType or Put | PutProduct |
| PUT /entityset(key)/cast | /Products(1)/Models.Book | PutEntityType or Put | PutBook |
Currently the built-in conventions do not cover all possible OData URIs. You can add new conventions by implementing the **IODataRoutingConvention** interface. This interface has two methods:
The **ODataPath** parameter represents the parsed OData resource path. It contains a list of **[ODataPathSegment](https://msdn.microsoft.com/library/system.web.http.odata.routing.odatapathsegment.aspx)** instances, one for each segment of the resource path. **ODataPathSegment** is an abstract class; each segment type is represented by a class that derives from **ODataPathSegment**.
The **ODataPath.TemplatePath** property is a string that represents the concatenation all of the path segments. For example, if the URI is `/Products(1)/Supplier`, the path template is "~/entityset/key/navigation". Notice that the segments don't correspond directly to URI segments. For example, the entity key (1) is represented as its own **ODataPathSegment**.
Typically, an implementation of **IODataRoutingConvention** does the following:
1. Compare the path template to see if this convention applies to the current request. If it does not apply, return null.
2. If the convention applies, use properties of the **ODataPathSegment** instances to derive controller and action names.
3. For actions, add any values to the route dictionary that should bind to the action parameters (typically entity keys).
Let's look at a specific example. The built-in routing conventions do not support indexing into a navigation collection. In other words, there is no convention for URIs like the following:
1. I derive from **EntitySetRoutingConvention**, because the **SelectController** method in that class is appropriate for this new routing convention. That means I don't need to re-implement **SelectController**.
2. The convention applies only to GET requests, and only when the path template is "~/entityset/key/navigation/key".
3. The action name is "Get{EntityType}", where *{EntityType}* is the type of the navigation collection. For example, "GetSupplier". You can use any naming convention that you like — just make sure your controller actions match.
4. The action takes two parameters named *key* and *relatedKey*. (For a list of some predefined parameter names, see [ODataRouteConstants](https://msdn.microsoft.com/library/system.web.http.odata.routing.odatarouteconstants.aspx).)
And of course Web API itself is open-source, so you can see the [source code](http://aspnetwebstack.codeplex.com/) for the built-in routing conventions. These are defined in the **System.Web.Http.OData.Routing.Conventions** namespace.