How should I organize this Instapaper-like functionality in Rails? - ruby-on-rails-3

Instapaper, if you don't know it, is a bookmarklet that saves your current URL to an account of yours. Essentially the bookmarklet loads a script on the page with parameters on that script's URL with something like
z.setAttribute('src', l.protocol '//www.instapaper.com/j/Jabcdefg?u='
encodeURIComponent(l.href)'&t=' (new Date().getTime()));
b.appendChild(z);
So that's sending a request to a user-based, obfuscated URL along with the current page's URL.
I'm wondering how a similar service would be set up in a Rails app. The work is clearly being done by something called, perhaps, parser, which would probably be a model (it will run an HTTP request, parse, and save the data, for example). Can you route directly into a model? Do you need a controller over it to handle incoming requests? (I've tried this last bit, and it auto-loads a view, which I don't need/want).
I'd love some advice on this general architecture. Thanks!

I guess you cannot route directly to a model.
So, you need a controller over it to handle incoming requests.
And use "render :nothing => true" if you don't want the view to be sent to the browser.

Related

Request URI too long on spartacus services

I've been trying to make use of service.getNavigation() method, but apparently the Request URI is too long which causes this error:
Request-URI Too Long
The requested URL's length exceeds the capacity limit for this server.
Is there a spartacus config that can resolve this issue?
Or is this supposed to be handled in the cloud (ccv2) config?
Not sure which service are you talking about specifically and what data are you passing there. For starters, please read this: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/414
Additionally it would benefit everyone if you could say something about the service you're using and the data you are trying to pass/get.
The navigation component is firing a request for all componentIds. If you have a navigation with a lot of (root?) elements, the maximum length of HTTP GET request might be too long for the given client or server.
The initial implementation of loading components was actually done by a POST request, but the impression was that we would not need to support requests with so many components. I guess we were wrong.
Luckily, the legacy POST based request is still in the code base, it's OccCmsComponentAdapter.findComponentsByIdsLegacy.
The easiest way for you to use this code, is to provide a CustomOccCmsComponentAdapter, that extends from OccCmsComponentAdapter. Then you can override the findComponentsByIds method and simply call the super.findComponentsByIdsLegacy and pass in a copy of the arguments.
A more cleaner way would be to override the CmsComponentConnector and directly delegate the load to the adapter.findComponentsByIdsLegacy. I would not start here, as it's more complicated. Do a POC with the first suggested approach.

RESTlet redirect sending browser riap URI

I'm using RESTlet to handle PUT requests from a browser and after a successful PUT, I want to redirect the browser to different web page.
Seems like a standard PUT->REDIRECT->GET to me, but I'm not figuring out how to do it in my RESTlet resource.
Here is my code after the PUT has done the requested work:
getResponse().redirectSeeOther("/account");
However that results in the browser getting:
Response Headers
Location riap://application/account
Of course, "riap" protocol is meaningless to the browser and "application" is not a server name. It seems like there ought to be a way to send a redirect back to the browser without building the entire URL in my redirectSeeOther() call. Building the URL seems like to could be error prone.
Is there an easy way to redirect without building the whole URL from the ground up?
Thanks!
Sincerely,
Stephen McCants
Although I am not 100% sure in what type of class you are trying to do this.
Try :
Reference reference = getRequest().getRootRef().clone().addSegment("account");
redirectSeeOther(reference);
I usually also then set the body as
return new ReferenceList(Arrays.asList(reference)).getTextRepresentation();
but that may not be necessary for all clients, or at all. I will usually use this style in a class that extends ServerResource - Restlet (2.0.x or 2.1.x).

Lithium PHP framework : How I can use AJAX request in this

I'm beginner to Lithium framework. Could anyone please help me to understand flow of ajax request in this framework via an simple example. e.g. I'm using jquery and I have to access a method in controller via ajax call and then need to display result in view. Controller function can be called from normal request as well as for ajax request.
Thanks in advance!
Perhaps if you posted a little bit of code, we could show you some code, in return.
By default, Lithium responds to HTML and JSON requests.
Suppose you have an action named index within PostsController, you would, by default, access it via /posts/index which would return HTML.
However, if you access /posts/index.json, you should get json output which you can process via jQuery. Of course, you'd have to comment out media.php in bootstrap.php and I'm also assuming you haven't changed the default routes.
There's a bit of info here as well, if you're interested.

Testing Rails/Rack applications using rails console

My simplistic understanding of the Rails stack is that it does the following (in general)
The input is a HTTP message (GET, POST, PUT, DELETE, HEAD), a URL, some (optional) cookies, a (optional) session token, and possibly some data packed up in JSON or XML format.
This HTTP message is handled by Rack which may run it through a set of "middleware" functions which add or remove data from the message, and may use the data to add, alter, or remove data from the program's data store.
The HTTP message at the output of Rack is sent to the Rails router, which maps it to a controller, an action, and a params hash with the session information, cookies, and other parameters in it. The data is dispatched to the appropriate controller.
The controller method parses the params, and algorithmically combines it with data from the database (via models), optionally changes data and then dispatches a set of variables starting with # to a view template.
The view template takes the data and merges it with the view template to form a view with the appropriate format (eg. HTML, JS, JSON, XML, etc), or it tells the caller (via a HTTP return code) to redirect to another URL.
What I would like to do with my Rails web application, using the Rails console is
Compose a valid HTTP message with URL, session ids, cookies, and encoded data (JSON or XML).
Inject this data into the Rack interface, and inspect what comes out before it is sent to the Rails router.
I would then like to then send that data to the Rails router and see what comes out before it goes to the controller.
I would then like to send that data to the controller and see what comes out before it is sent to the view template.
And I would then like to take that that data and run it through the view template and have display on STDOUT, or have it automatically open a web browser and see it render.
Are there any existing Rails tools which can do this? If not, can anybody point me to the Rails code where these interfaces occur?
Most of what your looking for is within the actionpack library of rails.
ActionDispatch handles the interface with rack, the middleware and the router. The request hits the router as the last piece of middleware. The router itself gets called within action_dispatch/routing/mapper. So if you want to intercept the request before it hits the router, inject your own piece of middleware before the routes get called.
Once the the router map verifies that it has a valid route it calls the application which is over in the railties library. This I believe then bumps you back over into actionpack into the ActionController middleware. I'm not sure exactly where you'd want to tie in to intercept before getting to the controller, but I'm guessing it would be somewhere around that ActionMiddleware class.
From there your off into actionpack. The render/redirect that your controller calls sets up what will happen within actionpack. I'm not sure exactly where AC calls into AP but you should be able to sift your way through it and find the path your looking for.
As for the response, your back to the middleware. Once rails has the view stitched together it basically unwinds itself and goes back down the middleware stack before sending the response back to Rack.
Hope that helps.

Is it REST if I pass the following URI /apps/{id}?control=start

I'm in the process of designing a REST API for our web app.
POST > /apps > Creates an app
PUT > /apps/{id} > Updates the app
I want to start the apps.
Is this REST and if not, how can I make it more RESTful?
POST > /apps/{id}?control=start
Sun Cloud API does this: http://kenai.com/projects/suncloudapis/pages/CloudAPISpecificationResourceModels
Or is it better to:
2. PUT /apps/{id} and include a status parameter in the response Json/XML?
3. POST /apps/{id} and include a status parameter in the response Json/xml?
4. POST /apps/start?app={id}
I think the right question here is more whether the HTTP verbs are being used as intended rather than whether the application is or is not as RESTful as possible. However, these days the two concepts are pretty much the same.
The thing about PUT is that whatever you PUT you should be able to immediately GET. In other words, PUT does a wholesale replacement of the resource. If the resource stored at apps/5 is something that has a "control" attribute as part of its state, then the control=start part should be part of the representation you put. If you want to send just the new piece of the resource, you are doing a PATCH, not a PUT.
PATCH is not widely supported, so IMHO you should use a POST. POST has no requirements of safety or idempotency; generally you can do whatever you want with a POST (more or less), including patching parts of a resource. After all that is what you do when you create a new item in a collection with a POST. Updating a portion of a resource is not really much different.
Generally though you POST new data in the request body, not as query parameters. Query parameters are used mostly for GETs, because you are, well, querying. :)
Does starting an app changes it state? (to "running", for example) If it does what you're actually doing is updating the state of the resource (application). That seems like a good use for the PUT operation. Although as Ray said, if control is part of the state of the resource, the body of the PUT request should contain the state you're updating. I believe a partial update would be possible (CouchDB uses this).
On the other hand, if starting an app means creating a new resource (representing the app execution, for example), the POST method would be a great fit. You could have something like this:
POST /app/1/start
Which would result in a HTTP/1.1 201 Created. Then, to access the information on the created execution, you could use a URL like this:
GET /app/1/execution/1
To me, this would seem like a good "Restful" approach. For more information, check out this article.
PUT apps/{id}
I would PUT the app to update it's status from off to on
I like to do something like,
POST /runningapps?url=/app/1