eZ Community » Blogs » Yannick Modah Gouez » My Journey With The REST API v2. Part 1

By

Yannick Modah Gouez

My Journey With The REST API v2. Part 1

Friday 27 September 2013 10:57:07 am

  • Currently 4 out of 5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

These past days I've been playing with the REST API v2 in the scope of my project that is to implement an Angular.js (angularjs.org) Front-End for eZ Publish

This blog post series will hopefully help you if you are on a journey to the Rild Rild Rest.

Introduction

First of all, let's talk about what led me to start querying this REST API I've beem hearing about for a while.

I am currently working on an angular.js based application that is consuming data from eZ Publish exclusively over its REST API. "Fancy uh" you might say.

Actually this is more like a challenge and an experiment to me. I think that the web is more and more aiming towards such "browser-side-computed-apps" so I want up-to-date.

Anyway, if you want to take a look at the foundations of this project you can check it out at https://github.com/yannickmodahgouez/eZangular fell free to clone, comment, PR or anything, It will be a pleasure.

Well let's get to the point now. While working on this project, I've came accross a few problems and surprises that I want to share  with you guys.

Roll Call :

Configuring eZ REST API for Session Based Authentication

Well, Session Based REST, might sound like an abomination to some people, but we DO need it in order to provide data for end-users ( let's say set-top-boxes, phablets or other thingies )

In order to enable it, you only have to disable basic HTTP authentication method provided by Symfony2.

Luckily enough, it's well documented, and it's here :  https://confluence.ez.no/display/EZP/REST+API+Authentication

To make it short, you just need to comment out the following block in <ezp-root>/ezpublish/security.yml :

 

#        ezpublish_rest:
#            pattern: ^/api/ezp/v2
#            stateless: true
#            ezpublish_http_basic:
#                realm: eZ Publish REST API

Dealing with CORS Standards

Now, second issue you might encounter if you are creating a JS app that consumes data from eZ REST API is the browser-side limitations for Cross Domain requests defined in the W3C CORS Standard ( http://www.w3.org/TR/cors/ )

First thing you might want to do is to set-up your apache conf in order to accept requests from your Origin Domain your.origin.domain.com

 Header set Access-Control-Allow-Origin "http://your.origin.domain.com"

 

Then, some browsers might try to fire an OPTIONS method to your eZ Publish server before sending the actual request, this is know as the "pre-flight" request.

Sadly, at the moment, eZ REST API v2 does not support this request, there are even two open issues about it, vote them up if you care :

https://jira.ez.no/browse/EZP-21044

https://jira.ez.no/browse/EZP-21118

So in our case, we need to find a workaround and you have two choices, fix it on eZ side or on you app side.
For maintenance purposes I chose to fix it on my app side by using the following trick :

 // we have to set "X-Requested-With" to empty in order to bypass CORS pre-flight OPTION request
 if(bypassCORS) RestangularProvider.setDefaultHeaders({"X-Requested-With" :""});

As you could guess, I am using restangular library for all REST calls. This line of code allows me to set the "X-Requested-With" header to an empty string, cancelling the pre-flight OPTIONS request. Cool.

Roles & Policies

Well, when everything is set and your requests are fired, you might end up with the following error while trying to access to the content data ( unless you are logged as an administrator ) :

 

 {
 "ErrorMessage": {
 "_media-type": "application/vnd.ez.api.ErrorMessage+json",
 "errorCode": 401,
 "errorMessage": "Unauthorized",
 "errorDescription": "User does not have access to 'versionread' 'content'",
 ...

 

Well, at the moment, accessing to the Fields ( or "datamap" for old schoolers ) needs to query for the version, and the current version cannot be accessed without a content/versionread policy, that is not available on the anonymous role by default. The worst part is that the limitation on the 'published' version doest not work. bummer.

This is documented in the following issue, once again, vote it up if you care : https://jira.ez.no/browse/EZP-20290

My workaround was to, of course, temporarily grant the 'content/versionread' policy to anonymous users. This is only OK because I'm working on a development environment.

If you app need to be in production soon, I would recommend you to add some extra security to avoid having your content/versionread browsed on anything else than your REST API and your backend by disabling the 'content/versionview' view on any siteaccesses without editing  functionnalities. Better than nothing.

 

Querying or Bulying ?

Having to access the Version to get the Fields... This brings up the last topic for this blog post.

For those who played with the Public API ( or read blog posts about it ) you probably know that it can lead to having very verbose queries. Well it's OK because it's PHP, it just bother coder without auto-completion.

The issue here is since the REST API v2 is coded on top of the Public API, you will need to query the server at least 5 times by locations, each query being a round-trip to the server.

Example :

In the current state of eZ Angular, for a location, I do simple things :

create a breadcrumbs, display an unformatted version of the fields and display the children.

Shoud be simple, but it's not. I need 17 GET Requests to the API to display this content for the homepage :

eZ Angular

17 GET Requests

And I don't event know the Fieldtype of my fields, meaning that I cannot process them without querying the server again.

Well, the eZ Gods on their eZ Olympus thought of us ! There come the views to our rescue !

The views in eZ REST API v2 are just like Views is SQL, you can store "pref-formatted" ways of displaying your content so that you don't have to buly your server ( btw mine is extremely under-optimized by the way ).
Well, that's you can understand from the documentation : https://github.com/ezsystems/ezpublish-kernel/blob/master/doc/specifications/rest/REST-API-V2.rst#views

But the harsh reality is that as for now (CP 2013.07) , it's not implemented yet and we still have pray  ( as in "pay for beers" ) to the eZ Gods so that we can use this functionnality ! Hundred Thunders !

 

  # Views
ezpublish_rest_createView:
    path: /content/views
    defaults:
        _controller: ezpublish_rest.controller.content:createView
    methods: [POST]
 
<strong># @todo this doesn't actually exist. Must generate a 404.</strong>
ezpublish_rest_loadView:
    path: /content/views/{viewId}
 
ezpublish_rest_loadViewResults:
    path: /content/views/{viewId}/results

 

Of course, and it goes for all stated issues before, you can go out there and implement them yourself ( just make sure you don't forget your Newline at EOF ).

OR you can wait patiently for those them to be implemented.

So the next episode of this article series will definitly be about how to implement those views and how to use them in an javascript front-end app.

Don't forget to check out my repository here : https://github.com/yannickmodahgouez/eZangular to get the code of my app.

By the way, a great thank to all who helped on this journey : Damien Pobel, Edi Modric and Philippe Vincent-Royol :)

See you in the next episode !

Your eZ Hero ;)

Proudly Developed with from