HATEOAS backend? - react-admin

I would like to use react-admin with my Restful HATEOAS inspired server.
Has anyone ever tried that?
Unfortunately, react-admin wants to work with id's and does not hand objects to the dataprovider. Especially in getManyReference it does not supply the referencing resource but only a fieldname (target) and an id. Is there any way to change that?
I have seen the hal implementation of a data provider and the graphql implementation. They grep an object's id from the "self" link which is basically perverting the whole idea of HATEOAS.
UPDATE: We now plan to slightly re-define the param target. It should contain a filter field name which together with param idcan be used to filter for referenced resource. Instead of denoting a field-name, we give the name of the referencing resource in target so that the dataprovider can fetch the record of the referencing resource, containing the links to subresources. The resource field passed to getManyReference is then used as name of the link. We then extract the URL from the referencing record, append query parameters, and, with some luck, bob will be our uncle... Didn't try yet, just mentioning that we are doing some research here.

If the id can be the string, you should make the id the entire absolute URL, because ultimately... in HATEOAS the URL is the globally unique id for any object.

Related

Use category name in Sitefinity blog URL

I followed the instructions here on establishing a new provider and generating custom URLs, and it works as expected. There doesn't seem to be a clear reference for what parameters can be utilized in the settings as the example given is very basic.
I want to use the category name of the post in the URL. I tried:
/[Category]/[UrlName]
but what I got in the frontend was:
http://localhost:60327/my-page/Telerik.OpenAccess.TrackedList%601[System.Guid]/my-post-name
I also tried
/[Category.Title]/[UrlName]
which just threw errors.
Anyone know how to do this, or better yet, a good reference for the parameters?
I don't think this is possible since the Category property is actually a collection (TrackedList).
In theory you would need one of the collection items, let's say the first one, and your URL expression would be /[Category[0].Title]/[UrlName], but this is currently not supported by the expression parser.
Also, the idea of making the URL dependent on a complex (related) field is not a good idea. If someone deletes that category, they will break all your blog post URLs.
I would suggest you to create a custom text field for the blog post item (ex: CategoryUrl) and then you should be able to set the URL format to /[CategoryUrl]/[UrlName]. Make sure CategoryUrl field is required.

Multiple endpoints to expose different views of the same resource

I'm struggling to find an answer to this (perhaps because I'm not asking the question properly) ...
I'm building API to expose resources for a basic social networking service I'm creating.
My understanding is that the structure of URLs in an API is essentially a hierarchy, directory like structure. I think that means I can have multiple endpoints to reach the same resources or collections of resource links.
For example:
I have an endpoint
www.domain.api.org/users/{:uid}/posts
Which will return all posts sent by the user or that the user is tagged in. Seems ok, but what if I have an endpoint such as:
www.domain.api.org/posts
Which when hit with a http GET will return all public posts (i.e. all users' posts plus his friends' and public posts).
The difference is that the first URL points to user owned resources whereas the second to public ones (of which the users posts are included of course)
Are these okay or am I doing it the wrong / less sensible way?
To reiterate, can I have multiple endpoints which point to different contexts/views of the same resource?
Basically multiple endpoints for the same resources should be avoided. However in this particular case it does make sense.
What you can do is to introduce optional query param userId to the following endpoint:
www.domain.api.org/posts/?userId=<userId>
If this substitutes the first endpoint you mentioned that's the way to go.
I would like to add ontop of #Opal's answer.
Are these okay or am I doing it the wrong / less sensible way?
Ideally, like Opal mentioned, you would use queryParams in your url. For many applications I have build, I don't know the uids returned from the api beforehand, so selecting an item and passing it inside my url as a query parameter makes sense. But it also has the added benefit of having your key inside your url, allowing you to bookmark it, pass the url to another user and they will automatically see the same data you want them to see.
To iterate: Is your current implementation wrong? No, but ideally you would use a combination of both route parameters are query parameters to achieve this
To create an endpoints, you have to be sure that you have these information at once:
Name of the endpoint
Status: activate or not (required) - is the endpoint activated or disable
Service profile (required) - ID of the Service Profile assigned to the endpoint.
Tariff profile (required) - ID of the tariff Profile assigned to the endpoint.
You can add another optional informations, and be sure of the structure of your endpoint.
Hope this helps you.

REST API: How to name a derived resource?

There is a gazillion of questions about RESTful interface naming conventions, esp. around singular vs plural resource names. A somewhat convention is:
GET /users Retrieve collection of users
GET /users/{id} Retrieve user
POST /users Create user
PUT /users/{id} Update user
DELETE /users/{id} Delete user
However, the above does not work when resource is a value derived from the environment.
My hypothetical application has the following endpoint:
GET /source Get information about the source of the query.
That responds with:
Referrer URL
Remote IP
Since source is derived from the environment, there is never more than one source, therefore calling the resource sources or providing sources/{foo} lookup is not practical.
Does REST style propose how to handle naming of these entities?
Dr. Fielding notes in section 6.2.1 of his famous dissertation :
..authors need an identifier that closely matches the semantics they
intend by a hypermedia reference, allowing the reference to remain
static even though the result of accessing that reference may change
over time.
Therefore, it makes sense to use plain source endpoint.
It would be a different thing if you wanted to provide more general service around IP address provided, like this one.

In what situation should the client choose the unique resource ID for REST URIs and in which should the server specify it?

It looks like there are two ways I can make my REST API. I can have users created with a POST without specifying the URI and it will create the user and return the URI OR I can have the create the users with a PUT and specify the URI themselves.
When should one be used over the other? The key difference here is that in one method MY system is deciding what the unique ID and thus URI for the resource should be, in the other situation THEY are specifying what it should be when I create.
It basically comes down to whether you are willing to cede the control of resource naming to the client.
The biggest issue simply being dealing with conflicts (If I PUT /photo.png and you PUT /photo.png, is that OK?).
Answer those questions, and you're on your way.
When your user is specifying the resource ID, they can PUT to the URI; the ID that they are performing the PUT to is the specification of the resource ID.
When you are specifying the resource ID, they can POST to the URI of the parent / group; your system will assign a URI to the resource, and return that to the client so they can reference their created resource.
The answer to this question hinges on two more specific questions:
Do clients know the location of the resource to be created? (This might be the case if, for instance, users are accessed via the name of the user rather than a server-assigned ID.)
Do clients have a full representation of the resource to be created? (This might not be the case if some portion of your resource is computed by the server.)
If the answer to both of those questions is 'yes', then a PUT is probably appropriate. If you answered 'no' to either, then you ought to stick with a POST.
I can have users created with a POST
without specifying the URI and it will
create the user and return the URI OR
I can have the create the users with a
PUT and specify the URI themselves.
When should one be used over the
other?
Use the first.
In RESTful HTTP the client should never construct URIs. The service should be well-connected, which means that the client should only ever follow URIs given by the server and make requests to those URIs.
It creates better separation between the client and server, and makes it easier to make changes to the service without breaking existing clients.
(And yes, lots of existing APIs get this wrong)
There's a really good post by Fielding related to this topic here:
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

When should an object be included as a member of another object, and when should it always standalone?

An example problem:
On Stack Overflow, a question page shows a number of different answers. In displaying these answers, the site also gives information about the author of the answer. This means that although the number of badges a given user has has nothing to do with an answer in and of itself, that data still needs to be retrieved in order to display the page.
From what I can see, there are three different ways to go about pulling this view data in a model:
A Post object could include a full User object as a member. The view would then access the user like this: $post->user->getReputation(). This seems cleaner, since a Controller could just request the posts and be done with it, but yet inefficient since a Post probably doesn't always need a full-blown User. I suppose it works well enough if the User object is relatively light, which it probably would be. The problem would then be that you would need to duplicate User retrieval code as part of the Post retrieval query.
The Post object could hold just an ID for a User. When the Post, or Posts, are returned to the Controller, the Controller could then extract the unique User IDs from the returned set and pass them to a User factory. The returned User objects would then be passed along with the original Posts set to the View as a separate collection. The view could then grab user info using something like $users[$post->getUserId()]->getReputation().
A hybrid approach: Include the User object inside the Post object, but have the unique id extraction and User retrieval as part of the Post retrieval method. i.e. Post::getPosts() would grab all relevant posts and convert them to objects with null User members, then it'd extract all user ids and pass them to User::getUsers(), then assign the Users to the relevant Posts before returning the set of Posts to the caller.
I guess what I'm getting at is, how do I know when an object needs to contain another object fundamentally? Is it unclean/a code smell to instead have such related objects returned separately, with neither object knowing the other has been retrieved. I'm leaning towards the separate retrieval concept - it seems the most efficient - but it really does feel like they're too related for that to make sense.
There is also a solution in between 1 and 2. You can have a lazy loading proxy for the user class. With this solution you can have best of both worlds because the proxy is interchangeable with the real thing so depending on the situation you can have the object itself or the proxy.
Edit:
I'll try to explain this with an example.
Say that you have a view where you don't need user info, then you can instruct/configure your post factory to use the lazy proxy (see wikipedia)for the user which will only contain an ID. So no access to users is needed.
In another view you occasionally need to access user info but only for some posts, here again you instruct/configure your factory to include the lazy proxy for the user.
But when you actually need access to the user info, you can access the proxy object that will then load the actual user object and redirect messages to it.
In yet another view you need both post and user info, so here you instruct your post factory to use actual user objects.
It seems to me that this is another case of dependency injection. A general enough idea that could help you.
DEPENDENCY INJECTION WIKI
Read something about the Inversion Of Control also.
why not add optional member to model to know informations?? you can ignore when you don't need and can use when you do need.