Probably the best option is to use a set prefix, such as "api/folders" and then match the path with a greedy wildcard, e.g. "{path*}". So your route would be:
This should catch the rest of the uri in a parameter called "path." Of course you'll now have to parse the path parts to find the correct file, but .NET is good at that. That at least works for MVC. I haven't tried this on Web API, but I assume it should
work. If not, I would call that a bug.
doesn't seem to work (not allowed to have a '/' in the end), so would I have to test whether I have a '/' in the end of my {*path} and then return the items if I do....
But... then I'd have to return a folder in one case and a list in the other... doesn't seem to fit...
doesn't seem to work (not allowed to have a '/' in the end), so would I have to test whether I have a '/' in the end of my {*path} and then return the items if I do....
But... then I'd have to return a folder in one case and a list in the other... doesn't seem to fit...
Could you use con-neg and the accept header to say you want info on the folder, verses you want the items in the folder? Possibly by a query parameter?
I would have the query parameter select different media formatters...
doesn't seem to work (not allowed to have a '/' in the end), so would I have to test whether I have a '/' in the end of my {*path} and then return the items if I do....
But... then I'd have to return a folder in one case and a list in the other... doesn't seem to fit...
So you want /api/folders/1/2/3 to return a folder and /api/folders/1/2/3/ to return the items in the folder?
If that's the case, I would advise against it. If you look at standard folder access on the web, these two are typically interchangable. I know they are technically unique, so it's not really bad, just a warning.
What exactly is a folder if not a collection of items? I think I'm missing what you want to do. Also, I don't think that "(*path}" will allow anything after. It means greedily consume everything else. I think your best bet is to check the path in your controller
and detect the trailing '/' to then retrieve either the folder or items. This is a limitation in the routing I've run into before with MVC. If you find a better way around it, I'm interested to know.
I'm just trying to figure out, what's the best to way to expose something similar to a folder structure using ASP.NET Web API... including adding, updating and deleting folders/files....
I can easily get a list of folders by using
http://localhost:.../api/folders
and a specific folder using:
http://localhost:.../api/folders/{id}
but what would be the logical way to get subfolders and files (items)??
http://localhost:..../api/folders/1/11/111
vill give me a single folder
http://localhost:.../api/folders/1/11/111/
could give me the folders/items underneath 111, but that's a bit hard to model in the API, since I'll hit the same GET as /1/11/111
so how would I get a list of (sub)folders/items underneath the 111 folder?? Right out of my head, I'd use something like:
http://localhost:.../api/folders/111/folders
http://localhost:.../api/folders/111/items
should that hit the 'folders' controller ?? if yes, it'll have to hit another actionmethod than the Get(int id), since the 111 is now referring to a 'parent'id... I could point to a specific action, GetSubFolders(int folderid) / GetItems(int folderid) in
the 'folders' controller, but would that work for PUT, POST and DELETE as well ??
or
should it hit another controller, with just one GET, PUT, POST and DELETE...
Just trying to figure out what would be the best way to implement this...
smolesen
Member
43 Points
37 Posts
Expose a hierarchy
Mar 27, 2012 01:02 PM|LINK
Hi
How would I expose a hierarchical structure (like a filesystem) in Web API....
Lets say I have something like:
FolderLevel1 -> FolderLevel2 -> FolderLevel3 -> Items
would I use a URL like:
GET: http://localhost:1234/api/folders/1/2/3 (seems to be quite difficult to define a MapRoute, since I don't know the dept of the hierarchy)
or
GET: http://localhost:1234/api/folders/1/subfolders (to get the subfolders of FolderLevel1)
GET: http://localhost:1234/api/folders/2/subfolders (to get the subfolders of FolderLevel2)
and how would I handle creation of a new folder having FolderLevel2 as a parent?
How do I handle Items within folder 3?
GET: http://localhost:1234/api/folders/3/items (to get the items within FolderLevel3)
or
GET: http://localhost:1234/api/items/of/3 (to get the items within FolderLevel3)
What's the best approach.. any ideas?
panesofglass
Member
730 Points
237 Posts
Re: Expose a hierarchy
Mar 27, 2012 01:37 PM|LINK
Probably the best option is to use a set prefix, such as "api/folders" and then match the path with a greedy wildcard, e.g. "{path*}". So your route would be:
routes.MapHttpRoute("Folders", "api/folders/{*path}");This should catch the rest of the uri in a parameter called "path." Of course you'll now have to parse the path parts to find the correct file, but .NET is good at that. That at least works for MVC. I haven't tried this on Web API, but I assume it should work. If not, I would call that a bug.
bradwils
Contributor
5779 Points
691 Posts
Microsoft
Re: Expose a hierarchy
Mar 27, 2012 09:19 PM|LINK
The syntax is "{*path}", but otherwise the advice is spot-on. :)
panesofglass
Member
730 Points
237 Posts
Re: Expose a hierarchy
Mar 27, 2012 09:24 PM|LINK
Doh! And I just used that, too, the corrected version, that is. Thanks, @bradwils.
smolesen
Member
43 Points
37 Posts
Re: Expose a hierarchy
Mar 30, 2012 12:37 PM|LINK
Wasn't aware I could use {*path}, but that solved the first issue... but how sould I ask for the items within a folder.... the resouce way would be:
GET: http://localhost:1234/api/folders/1/2/3/
But how do I setup a route for that?
routes.MapHttpRoute("items","api/folders/{*path}/");
doesn't seem to work (not allowed to have a '/' in the end), so would I have to test whether I have a '/' in the end of my {*path} and then return the items if I do....
But... then I'd have to return a folder in one case and a list in the other... doesn't seem to fit...
Jay_Harlow
Member
86 Points
26 Posts
Re: Expose a hierarchy
Mar 30, 2012 12:54 PM|LINK
Could you use con-neg and the accept header to say you want info on the folder, verses you want the items in the folder? Possibly by a query parameter?
I would have the query parameter select different media formatters...
Hope this helps
Jay
panesofglass
Member
730 Points
237 Posts
Re: Expose a hierarchy
Mar 30, 2012 01:50 PM|LINK
So you want /api/folders/1/2/3 to return a folder and /api/folders/1/2/3/ to return the items in the folder?
If that's the case, I would advise against it. If you look at standard folder access on the web, these two are typically interchangable. I know they are technically unique, so it's not really bad, just a warning.
What exactly is a folder if not a collection of items? I think I'm missing what you want to do. Also, I don't think that "(*path}" will allow anything after. It means greedily consume everything else. I think your best bet is to check the path in your controller and detect the trailing '/' to then retrieve either the folder or items. This is a limitation in the routing I've run into before with MVC. If you find a better way around it, I'm interested to know.
smolesen
Member
43 Points
37 Posts
Re: Expose a hierarchy
Mar 30, 2012 03:13 PM|LINK
I'm just trying to figure out, what's the best to way to expose something similar to a folder structure using ASP.NET Web API... including adding, updating and deleting folders/files....
I can easily get a list of folders by using
http://localhost:.../api/folders
and a specific folder using:
http://localhost:.../api/folders/{id}
but what would be the logical way to get subfolders and files (items)??
http://localhost:..../api/folders/1/11/111
vill give me a single folder
http://localhost:.../api/folders/1/11/111/
could give me the folders/items underneath 111, but that's a bit hard to model in the API, since I'll hit the same GET as /1/11/111
so how would I get a list of (sub)folders/items underneath the 111 folder?? Right out of my head, I'd use something like:
http://localhost:.../api/folders/111/folders
http://localhost:.../api/folders/111/items
should that hit the 'folders' controller ?? if yes, it'll have to hit another actionmethod than the Get(int id), since the 111 is now referring to a 'parent'id... I could point to a specific action, GetSubFolders(int folderid) / GetItems(int folderid) in the 'folders' controller, but would that work for PUT, POST and DELETE as well ??
or
should it hit another controller, with just one GET, PUT, POST and DELETE...
Just trying to figure out what would be the best way to implement this...
Jay_Harlow
Member
86 Points
26 Posts
Re: Expose a hierarchy
Mar 30, 2012 04:04 PM|LINK
I would use a query string to ask for folders or items:
http://localhost:.../api/folders/111?format=folders
http://localhost:.../api/folders/111?format=items
In your example, what happens when "items" is a valid folder or item under 111? With a query parameter it doesn't matter...
Hope this helps
Jay
smolesen
Member
43 Points
37 Posts
Re: Expose a hierarchy
Mar 30, 2012 04:49 PM|LINK
Wouldn't you expect
http://localhost:.../api/folders/111?format=folders
to be a folder where id=111 and format=folders
rather than:
list of subfolders underneath 111