On 03/30/2012 12:35 PM, Jan Provazník wrote:
On 03/28/2012 06:16 PM, Martyn Taylor wrote:
> On 03/28/2012 02:55 PM, Matt Wagner wrote:
>> On Wed, Mar 28, 2012 at 09:34:58AM +0100, Martyn Taylor wrote:
>> <snip>
>>> I actually think that the /conductor URL should be for the UI only
>>> and /conductor/api for the API.
>>>
>>> You could argue that the UI is simply a different content-type that
>>> our RESTful API supports and therefore all requests are the same but
>>> content-type is changed. However, I would argue that we treat the UI
>>> (in html) very differently from other content-types. The UI has
>>> server state, i.e. sessions (which are not RESTful) and also it
>>> doesn't only deal with resources. It returns a whole other bunch of
>>> stuff for layout and styling. This means that resources change
>>> structure depending on where they are accessed. They should be
>>> consistent.
>> This is an interesting point. But I wonder if the answer might actually
>> be that we're doing something wrong if our controllers are spending
>> more
>> time on UI setup than on their core function. Session should just be
>> used for authentication (and stashing flash messages as a UI
>> convenience), and the only change in resource structure should occur if
>> you request that it be displayed a different way -- e.g., XML, HTML
>> table view, HTML "pretty view", or JSON. You should have the same
>> information each way, just formatted differently. If this isn't the
>> case, I think we're doing something fundamentally wrong.
> The UI should not be part of the API. Instead it should be built on top
> of it. We are lucky in the sense that the API and the UI are co-located.
> But this does not mean they are one entity. Adding a separate html
> content-type to the API is a separate issue. If people think it is
> useful, either for constructing the UI or for REST clients. Then I'm all
> for that.
>
> The main difference between the UI and the API is that the UI is
> consumed by a user+browser. We add extra information in the controllers
> and views and store some session state to add to the user experience,
> the same way the CLI does a bunch of stuff on top of the Image
> management API to make it user friendly.
>
> Regardless of what you store in the session, if the UI stores state
> between requests about particular clients, then it is not stateless.
> Statelessness is one of the 6 REST contrainsts.
>>
>>> In addition to this I would recommend keeping the UI and API methods
>>> separate (but in the same controller) to keep things cleaner. There
>>> is a whole bunch of logic that goes towards layout, styling and a
>>> whole bunch of extra stuff is in there that isn't really relevant (in
>>> a RESTful API sense). For example, there's probably multiple
>>> unrelated resource sets in one page.
>> But the whole problem is that right now the UI and API methods _are_
>> separate, and this causes needless duplication and divergent code
>> paths,
>> where the API and UI methods inevitably do things a little differently
>> with negative consequences. I would argue that, rather than separating
>> them out, we should merge them and whip them into shape wherever making
>> a UI controller method work for API calls isn't trivial.
>>
>> -- Matt
> I was not arguing against merging the controllers. What I am saying is
> that the UI and the API are separate entities. If you want to serve them
> both from the same controllers then fair enough that makes sense. Helper
> methods can be written shared by both UI and API etc... However, what I
> want to avoid is one massive method that mixes the UI and API
> functionality. What I was more envisaging the API methods to offer a
> native ruby content type. That the UI methods can use. For example:
>
> @image = Image.all
> when format.xml?
> return @images.xml
> when format.json
> return @images.sjon
> else
> return @image
> end
>
> This way the UI methods can use the API methods in local method calls
> and then add whatever extra stuff it needs in order to make the service
> usable by a user+browser.
>
> regards
>
> Martyn
Hi Martyn,
do you mean inserting new service layer between models and controllers
(IOW this layer will be Rails free) or is the API layer supposed to be
part of controllers layer?
Jan
I meant the API should be part of controllers layer. But not
intertwined with the UI. The UI and the API are independent. The UI
could use the standard CRUD operations that the API implements through
local method calls.
For example:
Let's say we decide to implement filtering of images in the API.
/api/images => "images#list"
we would have this method on the Images controller (possible even in a
separate controller that we include in the UI controlller)
def list
if name = request.attributes[:name]
@images = Image.find_by_name(name)
else
@images = Image.all
end
if request.xml?
render :images.xml
end
end
now the UI wants to list images based on a filter it can use the API
method we have just defined.
/images => images#ui_list
def ui_list
@images = list
# Now do all the extra things you might need to do for the UI, show
the logged in user, get some information on user running instances:
@user = current_user
@running_instances = current_user.get_running_instances
end
So the UI is not part of the API. It builds on top of it. The UI does
not interact with the API through http but through ruby, by accessing
the ruby methods defined in the same controller. It might even be
possible just to use the same methods as the API to service the UI
requests and to do all the extra stuff in the view. But I think that's
likely going to over complicate things and possibly not acheivable, if
there is logic/data you can't access from with in the View without the
controller adding it.
What I meant was that the methods that service the API could and
should be used by the UI.