How should clients interact with services? - javascript

I have a client web application. The user clicks buttons, gives inputs, makes selections, etc... This is all done with Java using the Spring framework.
The client talks to another service that I have built in Java (with Vertx). This service talks to the database, handles caching, and the endpoints return values.
user navigates to web page--->client controller handles request mapping--->
--->request mapping uses controller method to return view--->
--->view's JS makes requests to service--->service returns model data
Now, I like the idea of control that Spring controllers offer. My client's pages use the Spring controllers to return views, and a small amount of model data.
However, what I am doing to call my service is: in my view's JS, I am making AJAX calls directly to the service. I mean, it works, and that is what was suggested for me to do, but I'm not sure if that is what I should be doing.
The alternative would be for my client to make JS calls to the client app's controller, and let the controller from my client app make requests to and receive responses from my service, then pass those responses back to my JS. I feel like this is probably the "cleaner" or "better" way to do this, but I am only about a year into programming with Java and don't know what the best way of doing this is. Essentially,
user navigates to web page--->client controller handles request mapping--->
--->request mapping uses controller method to return view--->client view's
JS makes requests to client controller--->client controller makes request
to service--->service returns data to client controller--->
client controller handles data and returns data to client view's JS
My gripes are that the JS exposes more than I would like it to in terms of the service's endpoints. Furthermore, I feel like using my client's controller to call the endpoints just seems... right.
I'd prefer input of experienced developers on what is right and/or wrong about these design patterns.

I've seen it successfully implemented both ways. Using a client controller is a fairly easy way of narrowing the exposed surface of the API (provided you lock-down access to the back-end services, otherwise you're just wasting your time). This method also allows you to turn the Client Controller into an adaptor to adapt the return values from the API into something more UI-centric (e.g. map codified values into text via an i18n file) and pare down any surplus data before it goes to the client.
However, there's an element of extra work or duplication as well as a performance overhead (hops, marshalling and unmarshalling).
If you ever suspect you're going to expose the underlying API or the client's usage of it is going to grow to the point where you've effectively created a shadow copy of your API, you should just put in place a robust Auth and Auth system to only allow calls from the appropriate places. This is not a trivial task, but would allow you to expose the API to other consumers.
The current and expected future usage of your API (but don't go all YAGNI on this!) should shape your decision. It may be appropriate to have the Client Controller layer doing filtering and shaping to avoid excessive client payload or not if you want the client to have a more transparent representation of your resources.

Related

In sails js should we plug a mongoDB database calculating app into a POST Controller?

The main interface app will return variables based on those initially POSTED by the client, and subsequent database calculations performed in real time by a dedicated engine.
In Sails can we plug the engine into a Controller used for returning the calculated variable?
What would be the best way to implement a real time link between the client and the engine ?
Sails comes with sockets support built in. You can transmit the data out of your controller back to the client via sockets to keep everything in sync.
Reference this page for sockets in sails:
https://gist.github.com/mikermcneil/6598661
As an aside, you could do everything using sockets, including the posting.
What is this 'dedicated engine'? Is this a separate service running somewhere else, or is it just logic for processing this data and handing it back to the controller?
If you want to put the data processing logic in the same app you can create a service which exports whatever data processing functions you need. Then in your controller that is handling the POST requests you can call on those services as needed, process the data, and emit it back to the client. All your sockets logic can go in that same controller since it is for communicating with the client interface. I would consider just moving all of it to sockets. If you look at the sails docs you will see that it has a similar interface with sockets where you can do standard CRUD operations: sockets.PUT, etc.
Sails.js WebSockets
No framework other than Sails, unless necessary for security purpose
Minimalist architecture implemented in Sails
1 POST API
1 POST Model
1 POST Controller
1 Socket per processing method
1 Socket switch within the Controller
Now if a secured framework integrates socket switching within controllers, that would come useful.
We may add middleware to the POST Model for the purpose of filtering text input data...

node.js and single page web application

I am looking at express.js for the back end and JS on the client side.
My app is a single page Web App.
The server will only serve JSON messages and my question is about "routing" for express.
Is one supposed to use routing to connect the UI and the server side business logic?
How will that work with my single page app?
so lets say, the client makes an Ajax call to the server looking for a value in the database and there is server side script that provides the JSON back to the UI. How is this UI and node script relationship setup?
Can someone shed some light on this?
Single page apps are those that live on a single HTML document. This means that if you want to display some different content to the user, depending on the state of the application, you will need to do some DOM manipulation (cutting out and replacing certain elements of the current document with different HTML) in order to update the 'view' that the user sees. Excuse me if this is obvious to you, please don't take offense. I figured I'd start from here. Hang with me and I'll explain how your routing situation is going to play out (more or less).
URLs are composed of a few different parts, each of which informs the browser of a particular bit of information that is required in order to download the resource that the user is attempting to access. Typically the resources that you are looking for are off on a server somewhere and the browser knows this because of pieces in the URL like 'protocol' ('http:') and 'host' ('www.mydomain.com'), so it goes off to that server to find what you're requesting. There are also 'query' parameters in URLs which provide some additional information to the server regarding a particular action, like the search terms of a search query. After the query parameters, comes the 'hash'. The hash is where the magic of single page apps happens... eh, well, kind of.....
First a bit about the hash. When you add a '#' to a URL, the browser then interprets the information that comes after it to be some location (element) within the currently displayed document. That means, if you have an element with an 'id' of 'main' and you add '#main' to the end of the URL, like so: 'http: //www.example.com#main', the browser will 'scroll' (typically 'jump') to the beginning of that element, so that the you can see it. Be aware, though, that if you type 'http://www.example.com/#main' (with the hash separated from the URL by a slash) then you will force a complete page reload and the browser will attempt to find a file by the name '#main' on the server (I bet it doesn't find it).
The takeaway here is that the browser will not attempt to navigate away from the current document if there is a hash in the URL, the exception being of course the case mention above, and this is great because single-page apps don't want to navigate away from the page or request a new document from the server. (See how routing is different for single-page apps?)
Now, this whole thing about the hash isn't vital to single-page apps, as you could make one without dealing with it all. A bunch of click handlers and DOM manipulation is all you'd need really... But, that would mean that users will have no way of sharing links to particular views in your app. The URL would never change, and we would never be able to navigate to any particular view directly. We'd always be starting from the starting position of your app, which could easily be a very annoying situation.
If your single-page app is going to have different views, and you want users to be able to navigate directly to particular ones via bookmarks or links, then you will need to implement a form of routing on the front-end in addition to the routing that you'll need to implement on the backend (routing for data API, etc.), which means that you will need to make use of the hash.
I don't want to get into how different frameworks accomplish routing on the front-end, but it's basically a matter of updating the browser's address field when the user clicks a link, and watching the address bar to determine what the current URL is and loading the HTML that is associated with that URL into the DOM in the designated location in the document tree.
So, within a single-page app, you have one route on the server that deals with rendering the app HTML document (index.html), and you have routes that are responsible for dealing with the data of your app (creating new instances in the database, logging in and out, editing or destroying instances in the DB, and fetching data...) which are called via AJAX requests.
This is actually a fairly complicated situation in that HTML5 allows us to be able to forgo the hash (with the help of some link rewriting on the server) and also be able to use the 'back' and 'forward' buttons as if we've actually navigated away from the original document (which we haven't because we have only pointed the browser to the exact same URL, only with modified hash values, so no new page loads have occurred). Traditional site navigation and linking can be achieved by utilizing the browser's History API, which is available for IE beginning with version 10 (I believe), the rest of the big browser vendors were already on to it quite a bit earlier, so frameworks that leverage this technology will allow your users to navigate your app without the hash in the URL. Explaining this is a diversion and not necessary for understanding routing in single-page apps, but it is interesting and you'll have to learn it eventually anyway, probably..
AJAX should be used to request JSON from the server. AJAX requests will always hit your server because you don't include the hash symbol in AJAX requests (it would be ridiculous to do so because the hash is meant only for in-document browsing), so server-side routes must be responsible for exposing your data API (consider a RESTful one). While this is not their sole purpose in single-page apps, it is perhaps their most important one.
Soooo, to wrap it up, you will have two sets of routes. One on the client (as part of a client-side framework like AngularJS or EmberJS, the list goes on... I prefer Angular, but there is a fairly steep learning curve for that one.), and one on the server. When you think about 'server routes' think data API. When you think of 'page routing', remember that this all gets handled on the client, by the javascript that you delivered with the initial server response (this is the one and only necessary server-side route involved with rendering HTML to the browser, loading your 'index.html' and all of the necessary scripts and stylesheets, etc). You will use express.static middleware to serve static files, so you don't have to worry about assigning routes for that stuff.
EDIT A quick mention of AJAX implementation.
On the server, you will have routes similar those that Alex has provided as examples and you will make calls to those URLs from the client using whatever XMLHttpRequest (XHR) object is exposed by your framework or library of choice. It is now considered more or less standard and best practice for frameworks/libraries to implement these requests as Promises http://wiki.commonjs.org/wiki/Promises/A. You should read a bit about it on your own, but I might be able to summarize it by saying that it is an asynchronous operation analogous to 'try, catch, throw' in synchronous operations. You will instantiate a promise object and through it you will attempt to load data from the server, for instance, via GET request. Make sure that you have assigned functions to handle requests made to the URL that you made the request to (server-side route)! This object that you instantiate and subsequently make the request to the server through, promises to return the result of the request to you once it comes back from the server (no matter whether it was successful or not) If it is successful, it will call a function that you have written and will supply it with the data from the server. If it fails, it will call a different function, also written by you, and will supply it with the error object (or 'reason' for failure), so you can handle the error appropriately.
Hope that helped answer your question.
You only have to route requests you serve dynamically. Your HTML, CSS, JS are all static assets. So all you need to handling routing for is your data.
It sounds like you want a Restful API, which basically means that you have URLs for specific resources, and HTTP verbs for manipulating them.
Something like:
GET /books.json - Get all books
POST /books.json - Create a new book with properties passed in the body of the request
GET /books/123.json - Get book with id of 123
PUT /books/123.json - Update an existing book with properties passed in the body of the request
This blog post seems to show how to set this up in Express.
Once you have a sane API delivering JSON, you just make your AJAX calls use it based on what objects you want to fetch.

How to Stream data from WebAPI method to a JavaScript client

I have a service method written in ASP.Net WebAPI :http://diningphilospher.azurewebsites.net/api/dining?i=12
and JavaScript client gets the response and visualizes it here
But the nature of Dining Philosophers problem is I never know when the Dead-lock or starvation will happen. So Instead of having a request/response I would like to stream the data through service method and client side JavaScript read the data I assume JSON asynchronously. Currently several post directs me towards changing the default buffer limit in WebAPI so you get a streaming like behavior.
what other(easy or efficient) ways exist to achieve this above behavior.
You can return PushStreamContent from ASP.NET Web API and use Server Sent Events (SSE) JavaScript API on the client side. Check out Push Content section in Henrik's blog. Also, see Strathweb. One thing I'm not sure about the latter implementation is the use of ConcurrentQueue. Henrik's implementation uses ConcurrentDictionary and that allows you to remove the StreamWriter object from the dictionary corresponding to the clients who drop out, which will be difficult to implement using ConcurrentQueue, in my opinion.
Also, Strathweb implementation uses KO. If you don't like to use KO, you don't have to. SSE JavaScript APIs have nothing to do with KO.
BTW, SSE is not supported in IE 9 or lesser.
Another thing to consider is the scale out option. Load balancing will be problematic, in the sense there is a chance that the load will not be uniformly distributed, since clients are tied to the server (or web role) they hit first.

REST Calls from Javascript VS ASP.NET Controller REST Calls

I am new to the REST world. I am writing an ASP.NET MVC application. My requirement is to make a few REST calls from the client. I can either choose to make these REST calls from Javascript or I can do that in the C# code in the Controller. Which method is recommended? According to my understanding, the Controller runs on the Web Server and the Javascript runs on the browser. So is there any perf degradation if the REST calls are made from the Web Server.
Can someone suggest me the general practice around this? Are there any security gotchas for the same?
Thanks
Let us consider the pros and cons of doing this Server side
PROs:
You can do other processing on the data using the power of the server
You are not subject to cross domain limitations like you would be in ajax
Generally you do not have to worry about your server being able to access the resource, whereas on client you are at the mercy of users net restrictions, firewalls etc
More control over your http response\request lifecycle
CONS:
You will have to consume more bandwidth sending the resulting data down to the client.
You may have to do more work to leverage good caching practices
Dependant on having certain server side libraries\framework elements
Now although we have a much bigger list of Pros than cons... in the majority of cases you will still want to do this on the client... because the issue of double handling the data is actually a very big one, and will cost you both time and money.
The only reason you should actually do it server side is if you need to do extensive processing on the data, or you cannot circumvent CORS (cross domain) restrictions.
If you are just doing something simple like displaying the information on a webpage, then client side is preferable.
It strongly depends on your situation. If you simple display this data in your page without any actions, you can get it from javascript. If you want to work with this data, transform it, join it with other data or else, i recommend do this operations on server so get this data on server too.

How to pass permission/authorization data to client side Javascript?

I have a javascript web application almost totally rendered client side.
The data is exchanged between client and server using models through a REST interface, then rendered using client side templates.
I have now the need to conditionally render some parts of the UI (or execute some operations) based on the user role/permission (authorization is server side model based ACL).
What is the best way to communicate permission data from server to client, taking into account that:
The models exchanged may have other embedded models with their
specific permission
I need to know also READ and CREATE permissions on different models (so the model object is not yet available client side)
Should minimize REST calls and DB calls
Your client should present controls to the user based on information returned by the server on a per-request basis. If the response from the server includes some information intended to be used to perform an action, the client should take that hint and maybe enable a button or make it visible or something.
Using this approach, you can define your ACL in terms of resource/privilege -- this model + that HTTP method. When the server is about to return a representation of a resource, it can include any options the user should see for that resource by polling the ACL for all privileges the user possesses for that resource (or others, like children/descendant resources.)
I am not sure what your application requirements are or if you are currently using any javascript frameworks. I would look here. Addy Osmani is very big in the javascript community and has helped create this javascript framework. It looks like it has the ability to handle your question. Here is a quote from the main README
The Sandbox includes a permissions layer, allowing you to configure permissions for widgets such as whether a specific widget has the right to render to the page etc.
There are a number of other javascript frameworks as well that you could look into that would make handing page level security a lot cleaner and means you wouldn't have to rewrite a lot of the code. Another example is Backbone Marionette It has the notion of composite views that would make it straightforward to implement page level security.
Finally another option is to not transfer your security information at all. Your REST API could only provide the model information that they have access too. You would need to write your client side templates in a way that would appropriately handle "missing" data so to speak.

Categories