Magnolia REST API - rest

Is there any way to request Magnolia REST API for list of products
which could be retrieved with equivalent of JCR SQL2
select * from [mgnl:product] where productName like '%Nikon%'
If it's only possible with custom rest end-point could you please point to tutorial.

Update as of Magnolia REST 2.1, using the v2 endpoint definition:
To answer the second question about node-types, here's what it looks like, as a YAML file in a light module, e.g. <module-name>/restEndpoints/delivery/my-products_v1.yaml:
class: info.magnolia.rest.delivery.jcr.v2.JcrDeliveryEndpointDefinition
workspace: products
rootPath: /
includeSystemProperties: false
bypassWorkspaceAcls: true
depth: 2
nodeTypes:
- mgnl:product
childNodeTypes:
- mgnl:contentNode
The Delivery endpoint config takes node-types to include.
nodeTypes specify the primary list of JCR node types to query—in your case mgnl:product;
childNodeTypes specify which child-nodes to include as JSON objects under the primary results, when depth is greater than 0.
With the above configuration, you may run the following requests to query products or get a single product, respectively:
GET <host>/.rest/delivery/my-products/v1?productName[like]=%25Nikon%25
GET <host>/.rest/delivery/my-products/v1/path/to/Nikon-1
This differs from Magnolia's former Nodes endpoint, which is not configurable, but only lets consumers exclude node-types.

Yes, you can use content delivery endpoint to do so. Syntax is like: GET /delivery/{endpoint-prefix}/v1?key1=value1&key2=value2
See https://git.magnolia-cms.com/projects/MODULES/repos/rest/browse/magnolia-rest-content-delivery for more details.

Related

What is the correct way in RESTful API paradigm to describe resource statistics?

Lets assume that we have some sort of users collection. Each user (single resource) has some sort of stats - number of comments, number of calls, number of anything. And each users collection may also have some sort of stats - global stats.
These stats can be anything from number of comments to something more complicated.
Currently I am thinking of two main ways of "integrating" stats to my RESTful API:
For each single resource user add special computed field - balance, mediumAgeOfMaleFriends etc. When performing GET request to user resource I'll loop for each field in query parameter fields and calculate corresponding values. Example: .../user/123?fields=balance,name,email,mediumAgeOfFemaleFriends
Under each resource create subresource called reports (or something like that), create report resource templates (with predefined configurations) and perform same GET requests like so: .../users/123/reports/1?from=...&to=...
But these two ways don't look like true RESTful ways.
I don't think there's a RESTful convention per-se for stats or reports. Both your options seem reasonable to me (leaning more towards Option 2 though).
Another alternative is to have a root resource for 'reports', e.g. /reports/user/123. This might come in handy in the future if you decide to extend reports to another resource, other than 'user'.
You can also have a look at HubSpots Analytics - Reports API for inspiration.

REST API - what is the proper way for sending ID on http request?

Let's say I have this URI endpoint:
:GET /v1/permissions
Which select all of the permissions on version 1.
One also can request this:
:GET /permissions
Which will request all permissions by the latest default version.
Now I want to select all of the permissions from a specific user.
I want to know what is the proper and respectable way to send the identifier of the user - in the URI endpoint OR in the http request headers OR as a GET param.
For example:
Method 1:
:GET /v1/groups/:id/permissions
Method 1.1:
:GET /v1/:id/permissions
Method 2:
:GET /v1/permissions,
"If-Match": "[REPLACE_ID_HERE]" (header)
Method 3:
:GET /v1/permissions/?groups=REPLACE_ID_HERE
All of them will work.
But which is the proper way?
But which is the proper way?
It's a common misconception.
The REST architectural style doesn't enforce any URI design (see notes below). It's totally up to you to pick the URIs that better identify your resources.
The URI syntax is defined in the RFC 3986. As general rule, the path is organized in hierarchical form (with segments separated by /) and can contain non-hierarchical data in the query component (starting with ?).
These approaches seem to be fine to identify the permissions of a particular group:
/v1/groups/:id/permissions
/v1/permissions?groups=id
The "right" approach would depend on your needs and how you model your API. In the first approach, the hierarchy expresses that the permissions belong to a particular group (the permissions depend on a group to exist). The second approach is more like filtering a collection of permissions by group.
Note 1: The REST architectural style is described in the chapter 5 of Roy T. Fielding's dissertation and it defines a set of constraints that must be followed by the applications that follow such architecture. However it says nothing about what the URIs must be like.
Note 2: The examples of a popular article written by Martin Fowler explaining a model defined by Leonard Richardson suggest a URI structure that looks friendly and easy to read.
Two points upfront:
There is no official REST specification issued by a central authority. The entire paradigm originates from a rather slim (yet ingenious) technical outline written by Roy Fielding in the year 2000.
However, there are several good books on the matter and hundreds of thousands of implementations that have led to a firm industry standard.
One of those standards is that REST Urls are specific to resources and ids embedded in those Urls reference resources of the same type. Thus GET /groups/:groupdId is orthodox (a standard implementation that matches the expectations of most programmers) whereas GET /groups/:permissionId is not.
Coming back to the 4 alternatives you contemplate:
Method 1:
:GET /v1/groups/:id/permissions
Is orthodox, since the resource managed by the endpoint is of type Group and :id is a Group id.
Method 1.1:
:GET /v1/:id/permissions
Is unorthodox since there is no indication of what resource type the Url refers to.
Method 2:
:GET /v1/permissions,
"If-Match": "[REPLACE_ID_HERE]" (header)
Is unorthodox, since resource ids are expected to be passed as part of the Url.
Method 3:
:GET /v1/permissions/?groups=REPLACE_ID_HERE
Is orthodox, since here the resource is Permission and the groupId is applied as a filter, for which request parameters are the adequate means.
The most common way of designing a REST API is following the resources (and - or sub-resources) structure. i.e. api url will start with your resource name followed by a unique ID for the resource in case of Single resource GET, PUT(update) or DELETE.
Ex :
1. /users/$unique_user_id - HTTP GET - Fetches the single user detail.
/users/$unique_user_id - HTTP PUT - updates the user details identified by the id with the related data.
/users/$unique_user_id - HTTP DELETE - Deletes the user identified by the ID.
If your case handles a well established relation between 2 resources you can handle them as sub-resources of the parent.
Ex :
/users/$user_id/permissions
/groups/$group_id/permissions
This model will suit if you won’t get a requirement to fetch permissions for multiple resources(kind of filtering)
Ex :
/permissions?group_ids=1,2,3
/permissions?user_ids=4,5,6
As per REST spec, you first need to determine what is the base resource you are requesting for. The name of the resource comes first in the URI. In your case, it's the Permission. Hence the URI will begin with permission, with an optional version prefix (as the whole API is versioned)
Following the resource name, you need to mention either a specific resource or a query parameters to get a broad list. Now here you have two options, based on what you are retrieving.
1) permission for a person: In this case, you need to put query param as the api itself won't be able to guess what is the id for. Hence it will be permissions/?personId=123
2) permission detail of a particular permission: Used when you have a list of permissions pre fetched, maybe as result of above api. In this case the identifier will belong to the resource itself, hence it will be specified as the resource identifier as permissions/5e55 where 5e55 is the primary key of the specified permission of whom detail is being sought after.
The major complexity in such design is properly identify the resource primary identifier and secondary identifier...
The primary identifier is put directly in type 2 and secondary is specified as query param.
All said, technically nothing will stop the either request style from working as long as you provide the parsing logic of the URI. REST just says that URI should be able to identify resource properly and does not impose an implementation requirement.

RESTful API with relationships

Lets assume I'm building an API for a restaurant and I have the following resources:
Donut(has_chocolate,has_sprinkles)
and
Receipt(cost,donut_id)
My Web App will want to display a table of receipts for the manager to view. Unfortunately the receipt object by itself isn't useful enough, the manager needs to see whether the donut has chocolate or not.
How best do I do this - I can think of 3 implementations:
1) Do a JOIN and return the receipt resource with the has_chocolate additional field
2) Do a JOIN and return the receipt resource with a donut object containing ALL relevant donut information
3) Pull in a page of receipt objects, collect and de-duplicate the donut_ids, and use them to pull in the required donut objects - either one at a time /donut/id, or all at once /donuts?ids=id1,id2,id3
A RESTful API should have endpoints that resolve to a resource or a collection of resources. You can then do an HTTP verb on that endpoint, in this case a GET. Therefore you need to make a decision about how do you define your resources for the API user?
Are there two resources, donuts and receipts, like in your SQL?
Do you want to define a donut as a resource that has a receipt as one of the fields?
Either is fine, the problem is when you start making routes that are a resource 'with something extra on top'. That starts to become hard for the consumer to understand and not RESTful.
If it were me I would choose option 3.
Define two separate endpoints for collections of donuts and receipts: /v0/donuts/ and /v0/receipts/
Allow the consumer to join on the client side by exposing the neccessary filters /v0/donuts/?ids=1,2,3,8
You could make a /v0/events/< id>/ route but seeing as the use-case is to always get a batch of donuts then this would result in too many round-trips for the consumer.
It also sounds like you want to paginate these collections. In this case you should define a max_page_size, default_page_size and you should return your client a next_page field in the response (which is null if it's the last page). You would also have to decide what to paginate on, probably the id in this case.

How to better specify kindo fo ID in RESTful service

I'm looking for an opinion about defining contract for standard GET/PUT/POST/DELETE methods.
We have resource, let's say Client, so route will be /clients
However, we have two types of id for the client. One is the ID generated by our system. On top of that we want optionally allow customers use external id, generated by customer themselves.
So, if customer never going to add clients to the system, don't really interested about integration, and need only use method GET to read customer, endpoint will be:
/clients/{id}
However, if they want full integration, with ability to add clients, and use some their id, we want give them ability to use their own id.
We considered four possible solutions:
1. /clients/external/{externaId}
2. /clients/ext-{externalId}
3. /clients/{externalId}?use-external-id=true
4. /clients/{externalId} with additional header -"use-external-id": true
We are leaning to options 3 and 4 (can be supported simultaneously) but concerns about "restfulness" of such approach. Any opinions on this? What would you choose and why?
REST says nothing about URLs.
How different are internal and external clients? If the only difference is the existence of an externalId property, just use the /clients endpoint and add the property to your client resource. Always assign and use the internal id property in your API, but allow queries to filter by the customer-provided external id also.
How about this:
/clients/client_id/1 - for automatically generated ids
/clients/external_id/d23sa - for filtering on the external_id field
This could be extended to generically filter on any field of a resource and is the approach my company used in developing SlashDB.

Modify Rest POST request behavior with query String

I have a resource which basically represents a number. I have two possible updates for this number: Set the number to a specific value or add a value to it. Now I'm confused if I can use the query string part of the URL to specify the desired behavior.
Something like this:
/resource/{id}/?mode=add
/resource/{id}/?mode=set
Or is there an alternative way two represent to update strategies for a rest resource?
An Alternative would be to extend the request body with this information but this since strange, since the request data should contain the data and not "meta information" for the request itself - as far as I understand REST apis.
The project is an ordinary angularjs (client) and java (server) project.