Attributes: Are the current REST-architecture tools limited to a tree-structure? - web-services

Historically operating system directory-structures have been trees:
C:
Windows
System32
Program Files
Common Files
Internet Explorer
And the REST architecture emulates the same thing:
http://...//Thomas/
http://...//Thomas/Mexico/Year2003/Photos
http://...//Thomas/Mexico/Year2007/Photos
http://...//Thomas/Finland/Year2005/Photos
http://...//Thomas/Finland/Year2010/Photos
http://...//Thomas/Finland/Year2010/Videos
http://...//Thomas/USA/Year2005/Photos
But, looking the current structure, I need to make searches:
All pictures that are not from
Finland?
All pictures taken in 2005?
All pictures in timeline?
It is not efficient to do a REST-interface with every tree-hierarchy combinations. You need more efficient information management; you need an attribute-system rather than a tree-structure.
(Oh, why the operating systems are not based on attributes?)
StackOverflow and Google seem to use attributes and syntax with "+"-marks like:
http://www.stackoverflow.com/Tags/asp.net+iis7
http://www.google.com/search?&q=iis7+asp.net
Today's frameworks like WCF and ASP.NET MVC have a good support for RESTful tree-structures. But is there support for attribute-structures? Wouldn't you call an attribute-structure still REST?
I would like to make an attribute-WebService and use it with a LINQ in Silverlight-client... Which is the best way to start? :-)

In order to create an effective REST interface you need to identify the resources that make sense for your client application. If you look at you use cases:
All pictures that are not from Finland?
All pictures taken in 2005?
All pictures in timeline?
The question you need to answer, is if this requires three resources or just one. I am assuming you want to have more than just these three queries, so therefore the most flexible solution is to define a generic resource which is a "collection of pictures".
/Thomas/pictures
From here, you want to be able limit contents of this resource by using query parameters.
/Thomas/pictures?country=not-finland
/Thomas/pictures?year=2005
In the case of the third item it may make sense to create a separate resource for that item.
/Thomas/PictureTimeline
There are other scenarios where it may make sense to create additional resource such as
/Thomas/FavouritePictures
The important thing is to identify what key concepts of your application you want to model as resources and then assign those resources an URL. Trying to do REST design via the URL space is going to make you bang your head against the wall.

What you are looking for are URI matrix parameters:
http://www.w3.org/DesignIssues/MatrixURIs.html
When to use query parameters versus matrix parameters?.

Related

Should I make requests to this API/change the structure of this API/use a DB instead?

That's what my Django Rest Framework API looks like. I want to use information from it on my website(where users can search for a flight and they will see the appropriate results). Of course I can filter the API in many ways, but the problem is I don't know what to do when it comes to searching for indirect flights. I also don't know what functions to use. I've already used fetch to create autocomplete but that's a different situation. Can fetch be used here too? Or maybe I should create the API in another way? And of course there's an option of using a db, the easiest one for me, but I would prefer using API. Maybe that's a dumb question, but I'm just confused

tastypie: why reference objects using uris rather than ids?

When creating or editing a model that contains a reference/foreign key to another object, you have to use the uri of that object. For example, imagine we have two classes: User and Group. Each Group has many Users and each User can belong to exactly one group.
Then, if we are creating a User, we might send an object that looks like this:
{"name":"John Doe", "group":"/path/to/group/1/"}
instead of
{"name":"John Doe", "group_id":1}
I believe this is related to one of the principles of HATEOAS, but I can't find the rationale for using the resource uri rather than the id. What are some reasons for using the uri?
(I'm not interested in opinions about which is better, but in any resources that can help me understand this design choice.)
I'll take a stab
The simplest reason is that surrogate keys like your 1 only mean something within the boundaries of your system. They are meaningless outside of the system.
Expanding on this, you could build your app such that there's no limitations on the URLs that identify groups, only the conformance of the resources gathered from the response of those URLS. Someone could add a user in your system that is in a group in the FaceBook system, as long as the two systems could negotiate what a group is. There are standards for concepts like group, and it's not impossible to do such a thing.
This is how most web apps work. EG: the citation links in a wikipedia article which can point to any other article (until the wiki trolls remove it for not being an appropriate citation resource...)
having your app work like this gets you closer to RESTful conformance. Whether or not you consider RESTful architecture a good idea is what you asked us not to discuss, so i won't.
Another often cited benefit would be the ability for you to completely re-key your setup. You may dismiss this at first...but if you really use 1 for id's, that's probably an int or long, and you'll soon run out of those. Also such an id means you have to sequence them appropriately. At some point you may wish you had used a guid as your id's. Anyone holding on to your old ID scheme would be considered legacy. The URLs give you a little abstraction from this..old url's remain a legacy thing, but it's easier to identify a legacy url than it is to identify a legacy id (granted not much...it's pretty easy to know if you're getting a long or a guid, but a bit easier to see a url as /old/path/group/1 vs /new/path/group/). Generally using URLs gives you a little more forward compatibility and room to grow.
I also find providing URLs as identifiers makes it very easy for a client to retrieve information about that thing. the self link is so VERY convenient. Suppose i have some reference to a group:1....what good is that? How many UI's are going to show a control that says "add group 1". You'll want to show more. If you pass around URLs as identifiers of selections then clients can always retrieve more information about what that selection actually is. In some apps you could pass around the whole object (which would include the id) to deal with this, but it's nice to just save the URL for later retrieval (think bookmarks). Even more importantly it's always nice to be able to refresh that object regularly in order to get the latest state of it. A self link can do that very nicely, and i'd argue it's useful enough to always include...and if an always included self link identifies the resource...why do you need to also provide your surrogate key as a secondary identifier?
One side note. I try to avoid services that require a url as a parameter. I'd prefer to create the user, than have the service offer up possible group memberships as links, then have the client choose to request those state transitions from non-membership to membership. If you need to "create the user with groups" i'd go with intermediate states prior to actual submission/commitment of the new user to the service. I've found the less inputs the client has to provide, the easier the application is to use.

Restful API - handling large amounts of data

I have written my own Restful API and am wondering about the best way to deal with large amounts of records returned from the API.
For example, if I use GET method to myapi.co.uk/messages/ this will bring back the XML for all message records, which in some cases could be 1000's. This makes using the API very sluggish.
Can anyone suggest the best way of dealing with this? Is it standard to return results in batches and to specify batch size in the request?
You can change your API to include additional parameters to limit the scope of data returned by your application.
For instance, you could add limit and offset parameters to fetch just a little part. This is how pagination can be done in accordance with REST. A request like this would result in fetching 10 resources from the messages collection, from 21st to 30th. This way you can ask for a specific portion of a huge data set:
myapi.co.uk/messages?limit=10&offset=20
Another way to decrease the payload would be to only ask for certain parts of your resources' representation. Here's how facebook does it:
/joe.smith/friends?fields=id,name,picture
Remember that while using either of these methods, you have to provide a way for the client to discover each of the resources. You can't assume they'll just look at the parameters and start changing them in search of data. That would be a violation of the REST paradigm. Provide them with the necessary hyperlinks to avoid it.
I strongly recommend viewing this presentation on RESTful API design by apigee (the screencast is called "Teach a Dog to REST"). Good practices and neat ideas to approach everyday problems are discussed there.
EDIT: The video has been updated a number of times since I posted this answer, you can check out the 3rd edition from January 2013
There are different ways in general by which one can improve the API performance including for large API sizes. Each of these topics can be explored in depth.
Reduce Size Pagination
Organizing Using Hypermedia
Exactly What a User Need With Schema Filtering
Defining Specific Responses Using The Prefer Header
Using Caching To Make Response
More Efficient More Efficiency Through Compression
Breaking Things Down With Chunked Responses
Switch To Providing More Streaming Responses
Moving Forward With HTTP/2
Source: https://apievangelist.com/2018/04/20/delivering-large-api-responses-as-efficiently-as-possible/
if you are using .net core
you have to try this magic package
Microsoft.AspNetCore.ResponseCompression
then use this line in configureservices in startup file
services.AddResponseCompression();
then in configure function
app.UseResponseCompression();

REST vs RPC for a C++ API

I am writing a C++ API which is to be used as a web service. The functions in the API take in images/path_to_images as input parameters, process them, and give a different set of images/paths_to_images as outputs. I was thinking of implementing a REST interface to enable developers to use this API for their projects (independent of whatever language they'd like to work in). But, I understand REST is good only when you have a collection of data that you want to query or manipulate, which is not exactly the case here.
[The collection I have is of different functions that manipulate the supplied data.]
So, is it better for me to implement an RPC interface for this, or can this be done using REST itself?
Like lcfseth, I would also go for REST. REST is indeed resource-based and, in your case, you might consider that there's no resource to deal with. However, that's not exactly true, the image converter in your system is the resource. You POST images to it and it returns new images. So I'd simply create a URL such as:
POST http://example.com/image-converter
You POST images to it and it returns some array with the path to the new images.
Potentially, you could also have:
GET http://example.com/image-converter
which could tell you about the status of the image conversion (assuming it is a time consuming process).
The advantage of doing it like that is that you are re-using HTTP verbs that developers are familiar with, the interface is almost self-documenting (though of course you still need to document the format accepted and returned by the POST call). With RPC, you would have to define new verbs and document them.
REST use common operation GET,POST,DELETE,HEAD,PUT. As you can imagine, this is very data oriented. However there is no restriction on the data type and no restriction on the size of the data (none I'm aware of anyway).
So it's possible to use it in almost every context (including sending binary data). One of the advantages of REST is that web browser understand REST and your user won't need to have a dedicated application to send requests.
RPC presents more possibilities and can also be used. You can define custom operations for example.
Not sure you need that much power given what you intend to do.
Personally I would go with REST.
Here's a link you might wanna read:
http://www.sitepen.com/blog/2008/03/25/rest-and-rpc-relationship/
Compared to RPC, REST's(json style interface) is lightweight, it's easy for API user to use. RPC(soap/xml) seems complex and heavy.
I guess that what you want is HTTP+JSON based API, not the REST API that claimed by the REST author
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Facebook style like system in modx cms (php)

Trying to build a simple like system in modx (which uses php snippets of code) I just need a button that logged in users can press which adds a 'like' to a resource.
Would it be best to update a custom table or TV? my thoughts are that if it is a template variable i can use getResource to sort by amount of likes.
Any thoughts on the best way to approach this or how to build this would help. My php knowledge is limited.
Depends how you are going to use it after and if you are storing more data than just a 'like' count. TV's are expensive on resources [even more so if you are going to whip through the entire resource set with getResources] so if you are going to do a lot of processing after the fact I would either look at a custom table ~or~ explore using property sets on your pages [I think it should be pretty easy to write a plugin that will update a page property]
I'd definitely go for a custom table.
While you could simply increment a numeric TV to count the amount of likes, you will come to a situation where anyone may be able to keep on liking a resource without limit - while you didn't specify the exact concept, that hardly can be desired. Using a custom table you could throw in a relational alias to the user ID that liked the resource, add a timestamp so you know when it happened, and let your fantasy run wild on additional features that are now open to you.
While not a hard requirement for custom tables, you will probably want to take the time to learn xPDO, which is the database abstraction layer MODX is based on. There's a great tutorial on the RTFM which walks you through it.