I am building a RESTful API for a web site that allows users to create widgets and tabs containing widgets (think igoogle.com/ netvibes.com) and I want to share my URL design for your insights.
Here are the simple rules:
-
There is a static list of widgetTypes available for a user to pick.
-
A user can create one or more widgetInstances of each widgetType.
-
A user can create one or more tabs/ dashboards containing widgetInstances
This API needs to only serve JSON that will be consumed by JavaScript. We can also assume that all authentication will be taken care of through cookies.
The API needs to serve:
-
CRUD of user’s Tabs
-
CRUD of specific user widgetInstances
-
Retrieval of all tabs for a user
-
Retrieval of all widgetInstances for a given tab.
-
Retrieval of all available widgetTypes for a user to add widgets from.
Design:
Tab controller:
widgetAPI.com/tabs -> Returns meta data (id, title) of all tabs available to a user.
widgetAPI.com/tabs/1 -> Returns meta data (title) of tab id 1. If sent with POST, updates tab id 1.
widgetAPI.com/tabs/1/widgets > Returns all widgetInstances of tab id 1.
Question 1: Ideally I’d like to follow the design of widgetAPI.com/tabs/1 also returning all the widgetInstances of the given tab but with that design, widgetAPI.com/tabs may return far too much data as I would have to return all the widgets for all the tabs. Hence I need to create a separate “widgetAPI.com/tabs/1/widgets” URL but that also has to return the tab meta data as I don’t want to make two HTTP calls to get meta data & widgets. Please advise as I am not sure of the best approach here.
widgetAPI.com/tabs/create -> Create a new tab
widgetAPI.com/tabs/delete/123 -> Delete tabid 123
Widget Controller:
widgetAPI.com/widgets/123 -> Return data for widgetInstanceId 123. Updates 123 if sent through POST.
widgetAPI.com/widgets/Create?typeID = 2 -> Creates a new widgetInstance of typeid = 2. This will only be a POST request so typeId could be a post parameter.
widgetAPI.com/widgets/delete/123 -> Delete widgetInstance 123
Question 2 So there is one rule I havent been able to fulfill yet. I need to return all the widgetTypes available and I am not sure how to fit this request into the previous two controllers. I am currently leaning towards just serving this separately. So something like widgetAPI.com/getWidgetTypes. Thoughts?
Thanks guys. If you could critique on the overall design, just address the questions or mention anything I should watch out for, that would be great as this is my first time designing a RESTful app. Thanks again.
A POST to the above URL should not update tab 1. A PUT to that URL should update tab 1.
To create a new tab, you should POST to widgetAPI.com/tabs
To delete tab 123, send a DELETE to widgetAPI.com/tabs/123
To update widget 123, send a PUT to widgetAPI.com/widgets/123
To create a new widget, send a POST to widgetAPI.com/widgets. The typeId should be part of the POST request body.
To delete widget 123, send a DELETE request to widgetAPI.com/widgets/123
Answer 1: I like the
widgetAPI.com/tabs/1/widgetsURL design. Also, I like the idea of making 2 separate calls for the metadata and the data.Answer 2: I think you should do this with a separate controller. I don’t like the URL though. Instead, I like HTTP GET
widgetAPI.com/widget-typesor justwidgetAPI.com/widgettypes.As a general rule, unless you want your clients to be able to create URL identifiers, follow this pattern:
URL: /whatever-resource
GET – returns all resources of this type
POST – create a new resource
URL: /whatever-resource/{id}
GET – return single resource with that id
PUT – update resource with that id
DELETE – delete resource with that id
You can also allow PUT requests to /whatever-resource/{id} to create a resource, but the client / user must specify the id (implicitly, the URL, since the URL contains the id). If you don’t want users to provide this, but rather have the server generate it, then POST to /whatever-resource to create the resource.