About logins and searches as resources

A reader posted a question in my blog post about REST services and URL’s about modeling search and login as a resource. As this is an important concept I decided not to add a comment but write another blog post about this.


About using http://localhost/login as a URL in a REST service

The URL http://localhost/login suggest that there is a resource login while login clearly is an action, not a resource. You don’t create or delete logins. Now you might create user sessions and in that case you might have a URL like http://localhost/UserSession where you can create and delete a users session.

Another, unrelated to the URL, thing here is that REST services should be stateless in order to promote scalability. Therefor it is better not to start a session, do a number of requests and log out. No you should consider each request completely unrelated to the others and if you need to authorize users then each request should contain the required user information.


About using http://localhost/books/search/robot to search for books with robots

This one is a little harder and depends on you point of view. I would argue that search is another action and not a resource so it should not be part of the URL. Maybe we use the http://localhost/books URL with a search method header, more about HTTP methods in another blog post. or a query string like http://localhost/books?$search=robot to indicate we want to search for books about robots.

Now someone could argue that the fact the books are resources and searching would return a collection of books and I would completely agree. So as it returns a collection of resources you might think this is an appropriate URL scheme to use and I would disagree. But I am also pragmatic in these cases and it is about the end result, not about being right or wrong. So of you want to use this URL to search go with it. Just remember I am not that pragmatic that I am also going to agree about the login Smile


How the URL is actually constructed using the WCF Web API

When we start constructing our URL there are three different parts that combine the complete URL. Given the URL http://localhost:28330/books/12345 the first part if the base address. This is the http://localhost:28330/ part and is determined by IIS in the case of managed hosting or the base address specified in the case of self hosting. The next part of books/ and that is determined by the path specified when we do the routes.MapServiceRoute<T>(path) like in this example:

public static void RegisterRoutes(RouteCollection routes)




    var builder = HttpHostConfiguration.Create();

    routes.MapServiceRoute<BooksService>("books", builder);



        "Default", // Route name

        "{controller}/{action}/{id}", // URL with parameters

        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults




The last part, the 12345 in the example URL, is determined by the UriTemplate property of the WebGetAttribute used in our service contract.  This can be an empty string, as in the GetBooks() example, to use the service route of http://localhost:28330/books which is typically reserved for the collection. It can also be templated, like in the GetBook() example, to specify variable parts that match input parameters. In this case {id} matched the id parameter. This can be further enhanced with fixed and variable strings like http://localhost:28330/books/12345/orders/6789 and a template of /{id}/orders/{orderId} to return a specific order from the collection of orders containing book 12345.

[WebGet(UriTemplate = "")]

List<Book> GetBooks()


    var result = _repo.GetBooks();

    return result;



[WebGet(UriTemplate = "/{id}")]

Book GetBook(int id)


    var result = _repo.GetBook(id);

    return result;






One thought on “About logins and searches as resources

Leave a Reply

Your email address will not be published. Required fields are marked *