Build HTML page via PHP or Javascript? Server-side vs. Client-side - server-side

Helo,
So I have a web server that generates a PHP object, and I build the webpage depending on that object (I have a HTML builder that literally echo the commands) and it is going great as I am using OOP so I maintain my code easily.
I understand that load-wise, it is a choice between server-side and client-side load and this is not a concern for now. Please correct me if I am wrong, and let me know your thought about this if you have any.
I also have a JS code to work with the PHP-built HTML page, and I can recognize two types of pages now, one of them confuses me a bit:
Passive Webpage
It can only display data and does not send feedback to the server. These webpages can either be done via PHP or Javascript, I see no difference there.
Active Webpage
This type is for pages that sends and receive (AJAX and others) requests from the server. Now I have two options which I can not decide over:
Build a PHP object, and pass it to JS to build the HTML.
In this case, JS should be aware of the full object, and it can easily manipulate it and make feedbacks. But, that would be making both JS and PHP understand the object, which means double the work on that field.
In this case, exchanging updates should be swell.
Build an HTML completely using PHP
This option requires JS to be aware of few, and not all, parts of the object (the parts that need update). This requires less work on JS, as it postpones possible work for the future (i.e. each new part of the object that needs updating should be understood be JS).
Now, I am kinda sure the second option is better, but the first option is faster for now (as I would like to have a working DEMO soon). At the same time, I am not totally sure, and I do not want to go too deep that it becomes harder to make a change of heart later on. What do yous think?
In case this was not clear enough, I will explain with an example.
PHP
Class A {
protected $_name;
protected $_id;
function Update( $aInstance ) {
// Give it an object, and it updates it. In case JS exchanges the whole object
}
function UpdateName( $newName ) {
// Updates the name only. Used in case JS updates parts of the object.
}
// Other setters, too.
function Draw() {
// Either returns the object as JSON or echos the HTML code.
}
}
class B inherits {
protected $_age;
function Update( $bInstance ) {
paret::Update( $bInstance );
// Update yourself, too.
}
// Other setters, too
function Draw() {
// Special draw, call parent's, or add to it
}
}
JS 1st option
var object;
function Draw( object ) {
// Handle all parts of the object.
}
function UpdateName() {
// Whatever happens when the name changes.
}
JS 2nd option
var header;
function DrawHeader() {
// Display the header somehow
}
var DrawName() {
// Display the name somehow
}
function UpdateName() {
// Whatever happens when the name changes.
}

As I understand the question is about handling HTML generation on the client side (JS) vs the server side (PHP). In almost all the modern web applications, the HTML part is now being handled on the client side. The HTML is generated either through providing static HTML files or through the JS based UI frameworks such as Angular/React or a combination of both. The idea of using server side code to generate HTML is pretty outdated now and there are very valid reasons for that. Please read about separation of concerns and MVC (model view controller) architecture. In simple terms, below are the reasons about why server side code should never handle HTML for most cases:
1) The biggest reason: to keep the user interface code separate from the server side code. If the UI is generated using server side code then it does not allow you to change the server side framework in the future. In this example, let's say if it would need to use Java or Go or Scala instead of PHP, then the HTML generation logic will also have to be moved or rewritten. However if your JS code is handling all the data via JSON, then the PHP code can be easily replaced with another language while keeping the JSON format same as before.
2) Any change in the HTML code will require recompilation, rebuild and re-deployment of the server side code if the HTML code is generated via server side code. However if it is kept on the client side, then no recompilation is required.
3) The HTML and UI is part of front-end engineering while server side is back-end engineering. So if the HTML code is written in the server side then it becomes very hard for front and backend engineers to collaborate and work on the same file, we definitely do not want this situation.
4) There are much better tools available for HTML design and manipulation that run on the client side and not on the server side.
5) If HTML generation happens on the server side, the same code to generate HTML is executed over and over again for each request. This is a waste of resources. Instead, if the HTML generation happens on the client side, the browser (JS code) will have to perform the HTML generation which significantly reduces the load on the server side.
There are numerous other reasons very well explained than how I managed to. In short, the HTML generation on the PHP side is not at all a good idea. Hope that helps!

Related

How to serve pre-rendered data-bindable templates

There are a lot of data-binding client-side frameworks these days (Ember, Backbone, Knockout and Angular are the popular ones I'm aware of).
The problem with all these frameworks is the initial load. You have to mark your HTML up with placeholders, and depending on how it's done, the client will either see empty page chunks, or random {{ markup }}. Further, most of these templates are parsed client-side, rather than pre-compiled.
Ideally, when the user first comes to the site, they would be served some pre-rendered HTML with all the data filled in, and that would give them something to look at while all the pre-compiled JavaScript templates load and the data-bindings kick-in. From there on out, it would use client-side routing and we would just have JSON on the wire.
I can do half of this already with Jade or a handful of other template languages that can be rendered server or client-side. The thing I can't figure out is how I would get this to play nicely with one of those frameworks.
For example, in Knockout, your view might look like this:
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
In Jade, I would define the same template like this:
p First Name
b= firstName
p Last Name
b= lastName
Which, for the curious, gets compiled to this:
function anonymous(locals) {
var buf = [];
var locals_ = locals || {}, firstName = locals_.firstName, lastName = locals_.lastName;
buf.push("<p>First Name <b>" + jade.escape(null == (jade.interp = firstName) ? "" : jade.interp) + "</b></p><p>Last Name <b>" + jade.escape(null == (jade.interp = lastName) ? "" : jade.interp) + "</b></p>");
return buf.join("");
}
Which is super quick to render either server- or client-side.
To get the data-binding to work, however, I would have to doubly annotate the source:
p(data-bind='text: firstName') First Name
b= firstName
p(data-bind='text: lastName') Last Name
b= lastName
i.e., put each placeholder variable in there twice, in two different formats.
(Fortunately, most of these frameworks take some sort of JSON object for the View Model (I believe), which I could serve directly to Jade or the framework, so that part shouldn't be an issue.)
I would very much like to avoid that but I can't think of how this might be possible without writing my own templating language which has a strong dependency on the frontend framework.
Is there a way to do this without a lot of pain? Using any of the above frontends or any JS-compilable templating language? Perhaps via some plugins/extensions rather than having to redefine it at a core level?
You might want to try angular, with node:
https://www.npmjs.com/package/ng-node-compile
Airbnb released a library called Rendr which lets you render your Backbone app server-side.
Facebook's ReactJS implements a virtual DOM that lets you render the entire UI server-side (in Node).
Angular 4+ has now Angular Universal, which allows SPA developed with Angular 2+ to be rendered in client side or in server side (with NodeJs or even Asp.Net Core).
The tricky thing is that ANYTHING that relies on window, sessionStore, localStore, etc. won't be executed in server side, because there is no browser in server side environment. So keep it in mind if you develop a SPA and are planning on rendering at server side to become SEO friendly.
React and VueJs are also frameworks/libraries that can be used for universal applications (to be rendered at server side and serve already rendered content to the browser)

CFInclude vs Custom Tag vs CFC for Presentation and Security

I'm just starting out with ColdFusion OOP and I am wanting to make a DIV which shows different links to users depending on what page they are on and what login rights (role) they have. Basically a 'context' menu.
Should I put this toolbar/navigation DIV in a .cfm or .cfc file?
To reiterate; The cfm or cfc file needs to know what page the user is on and will also check what role they have. Depending on these two pieces of information it will display a set of links to the user. The role information comes from the database and stored in a SESSION variable, and to find out what page they are on I guess it could use #GetFileFromPath(GetBaseTemplatePath())#.
My first thought was to have a normal .cfm file, put all the presentation and logic in that file (the HTML and lots of <cfif> statements) to ensure the correct information is displayed in the DIV, and then use <cfinclude> to display it on the page. Then I started thinking maybe I should make a Custom Tag and ask the calling page to pass in the user's credentials and the #GetFileFromPath(GetBaseTemplatePath())# as arguments and then have that Custom Tag return all the presentational data.
Finally I guess a CFC could do the above as well, but I'd be breaking the 'rule' of having presentational and logic data in a CFC.
Any suggestions on the best practice to achieve what I'm trying to do? It will eventually serve thousands of customers so I need to make sure my solution is easy to scale.
Anything that outputs HTML to the screen should be in a .cfm file.
That being said, depending on your need, you could have methods in a CFC that generate HTML, but the method simply returns the HTML as a string.
In programming, there are very few absolutes, but here is one: You should NEVER directly output anything inside of a function or method by using output="true". Instead, whatever content is generated, it should be returned from the method.
If you will have a need to use this display element more than once, a custom tag might be the best way to go rather than an include.
I see security as being a combination of what menu items I can see and what pages can be ran.
The main security function is inside of the main session object
On the menus
I call a function called
if (session.objState.checkSecurity(Section, Item) == 1)
then ...
For page security
function setupRequest() {
...
if (session.objState.checkSecurity(getSection(), getItem()) == 0) {
location("#request.self#?message=LoginExpired", "no");
return;
}
...
}
The particulars of what checkSecurity can do varies from application to application, but it is tied into how FW/1 works. The following security variations exist:
session.objState.checkSecurity(getSection())
session.objState.checkSecurity(getSection(), getItem())
session.objState.checkSecurity(getSection(), getItem(), Identifier)
None of the presentation files know anything about security.
Rules by which I live:) :
No CF business logic in CFM files. Just use some service which will serve template and provide needed data.
navService = com.foobar.services.Navigation(form, url);
and later output #navService.GetNavConent()#
No direct output from CFC files, functions should always return content. For example, make one function which makes one link based on some logic, second which wraps that and returns to cfm template.
Also one more hint, avoid using application and session scopes in your services.
This makes refactoring, testing and debugging too difficult.
For session you can make session.currentUser , CurrentUser.cfc which provides all things you need. e.g. session.currentUser.isAuthorized("backend/administration") and if true, show link to backend/administration.
Same for application, if you need locale, applicaiton wide setting or some singleton, make application.applicationSettings, ApplicationSettings.cfc and use that to retrieve all info you need in cfc's.
These rules will make your application to be easier to test and debug, and really easy to migrate tomorrow on some javascript based UI like Angular or backbone.js since all th edata you need is already in CFC and theoretically you just need to put remote in CFC or make some remote facade in the middle and you're done.

Save data through a web service using NHibernate?

We currently have an application that retrieves data from the server through a web service and populates a DataSet. Then the users of the API manipulate it through the objects which in turn change the dataset. The changes are then serialized, compressed and sent back to the server to get updated.
However, I have begin using NHibernate within projects and I really like the disconnected nature of the POCO objects. The problem we have now is that our objects are so tied to the internal DataSet that they cannot be used in many situations and we end up making duplicate POCO objects to pass back and forth.
Batch.GetBatch() -> calls to web server and populates an internal dataset
Batch.SaveBatch() -> send changes to web server from dataset
Is there a way to achieve a similar model that we are using which all database access occurs through a web service but use NHibernate?
Edit 1
I have a partial solution that is working and persisting through a web service but it has two problems.
I have to serialize and send my whole collection and not just changed items
If I try to repopulate the collection upon return my objects then any references I had are lost.
Here is my example solution.
Client Side
public IList<Job> GetAll()
{
return coreWebService
.GetJobs()
.BinaryDeserialize<IList<Job>>();
}
public IList<Job> Save(IList<Job> Jobs)
{
return coreWebService
.Save(Jobs.BinarySerialize())
.BinaryDeserialize<IList<Job>>();
}
Server Side
[WebMethod]
public byte[] GetJobs()
{
using (ISession session = NHibernateHelper.OpenSession())
{
return (from j in session.Linq<Job>()
select j).ToList().BinarySerialize();
}
}
[WebMethod]
public byte[] Save(byte[] JobBytes)
{
var Jobs = JobBytes.BinaryDeserialize<IList<Job>>();
using (ISession session = NHibernateHelper.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
foreach (var job in Jobs)
{
session.SaveOrUpdate(job);
}
transaction.Commit();
}
return Jobs.BinarySerialize();
}
As you can see I am sending the whole collection to the server each time and then returning the whole collection. But I'm getting a replaced collection instead of a merged/updated collection. Not to mention the fact that it seems highly inefficient to send all the data back and forth when only part of it could be changed.
Edit 2
I have seen several references on the web for almost a transparent persistent mechanism. I'm not exactly sure if these will work and most of them look highly experimental.
ADO.NET Data Services w/NHibernate (Ayende)
ADO.NET Data Services w/NHibernate (Wildermuth)
Custom Lazy-loadable Business Collections with NHibernate
NHibernate and WCF is Not a Perfect Match
Spring.NET, NHibernate, WCF Services and Lazy Initialization
How to use NHibernate Lazy Initializing Proxies with Web Services or WCF
I'm having a hard time finding a replacement for the DataSet model we are using today. The reason I want to get away from that model is because it takes a lot of work to tie every property of every class to a row/cell of a dataset. Then it also tightly couples all of my classes together.
I've only taken a cursory look at your question, so forgive me if my response is shortsighted but here goes:
I don't think you can logically get away from doing a mapping from domain object to DTO.
By using the domain objects over the wire you are tightly coupling your client and service, part of the reason to have a service in the first place is to promote loose coupling. So that's an immediate issue.
On top of that you're going to end up with a brittle domain logic interface where you can't make changes on the service side without breaking your client.
I suspect your best bet would be to implement a loosely coupled service which implements a REST / or some other loosely coupled interface. You could use a product such as automapper to make the conversions simpler and easier and also flatten data structures as necessary.
At this point I don't know of any way to really cut down the verbosity involved in doing the interface layers but having worked on large projects that didn't make the effort I can honestly tell you the savings wasn't worth it.
I think your issue revolves around this issue:
http://thatextramile.be/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/
Are you or are you not going to send ORM-Entities over the wire?
Since you have a Services-Oriented architecture.. I (like the author) do not recommend this practice.
I use NHibernate. I call those ORM-Entities. They are THE POCO model. But they have "virtual" properties that allow for lazy-loading.
However, I also have some DTO-Objects. These are also POCO's. These do not have lazy'loading friendly properties.
So I do alot of "converting". I hydrate ORM-Entities (with NHibernate)...and then I end up converting them to Domain-DTO-Objects. Yes, it stinks in the beginning.
The server sends out the Domain-DTO-Objects's. There is NO lazy loading. I have to populate them with the "Goldie Locks" "just right" model. Aka, if I need Parent(s) with one level of children, I have to know that up front and send the Domain-DTO-Objects over that way, with just the right amount of hydration.
WHen I send back Domain-DTO-Objects's (from client to the server), I have to reverse the process. I convert the Domain-DTO-Objects into ORM-Entities. And allow NHibernate to work with the ORM-Entities.
Because the architecture is "disconnected", I do alot of (NHiberntae) ".Merge()" calls.
// ormItem is any NHibernate poco
using (ISession session = ISessionCreator.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.BeginTransaction();
ParkingAreaNHEntity mergedItem = session.Merge(ormItem);
transaction.Commit();
}
}
.Merge is a wonderful thing. Entity Framework does not have it. Boo.
Is this alot of setup? Yes.
Do I think it is perfect? No.
However. Because I send very basic DTO's(Poco's) that are not "flavored" to the ORM, I have the ability to switch ORM's without killing my contracts to the outside world.
My datalayer can be ADO.NET, EF, NHibernate, or anything. I have to write the "Converters" if I switch, and the ORM code, but everything else is isolated.
Many people argue with me. They said I'm doing too much, and the ORM-Entities are fine.
Again, I like to "now allow any lazy loading" appearances. And I prefer to have my data-layer isolated. My clients should not know or care about my data-layer/orm of choice.
There are just enough subtle differences (or some not so subtle ones) between EF and NHibernate to screwball the game plan.
Do my Domain-DTO-Objects's look 95% like my ORM-Entities? Yep. But its the 5% that can screwball you.
Moving from DataSets, especially if they are populated from stored-procedures with alot of biz-logic in the TSQL, isn't trivial. But now that I do object model, and I NEVER write a stored procedure that isn't simple CRUD functions, I'd never go back.
And I hate maintenance projects with voodoo TSQL in the stored procedures. It ain't 1999 anymore. Well, most places.
Good luck.
PS Without .Merge(in EF), here is what you have to do in a disconnected world: (boo microsoft)
http://www.entityframeworktutorial.net/EntityFramework4.3/update-many-to-many-entity-using-dbcontext.aspx

Forcing ASP.net webservice to return JSON

I have an ASP.net web service that I'm using for a web application which returns a either XML or JSON data to me, depending on the function I call. This has been working well thus far, but I've run into a problem. I want to create an "export" link on my page that will download a JSON file. The link is formatted very simply:
Export This Item
As you might imagine, this should export item 2. So far so good, yes?
Problem is that since I'm not specifically requesting that the accepted content type is JSON, ASP.net absolutely refuses to send back anything but XML, which just isn't appropriate for this situation. The code is essentially as follows:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public Item ExportItem(int itemId)
{
Context.Response.AddHeader("content-disposition", "attachment; filename=export.json"); //Makes it a download
return GetExportItem(itemId);
}
Despite my specifying the ResponseFormat as JSON, I always get back XML unless I request this method via AJAX (using Google Web Toolkit, BTW):
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, "mywebserviceaddress/ExportFunc");
builder.setHeader("Content-type","application/json; charset=utf-8");
builder.setHeader("Accepts","application/json");
builder.sendRequest("{\"itemId\":2}", new RequestCallback(){...});
That's great, but AJAX won't give me a download dialog. Is there any way to force ASP.net to give me back JSON, regardless of how the data is requested? It would seem to me that not having a manual override for this behavior is a gross design oversight.
QUICK ANSWER:
First off, let me say that I think that womp's answer is probably the better way to go long term (Convert to WCF), but deostroll led me to the answer that I'll be using for the immediate future. Also, it should be noted that this seems to work primarily because I wanted just a download, may not work as well in all situations. In any case, here's the code that I ended up using to get the result I wanted:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public void ExportItem(int itemId)
{
Item item = GetExportItem(itemId);
JavaScriptSerializer js = new JavaScriptSerializer();
string str = js.Serialize(item);
Context.Response.Clear();
Context.Response.ContentType = "application/json";
Context.Response.AddHeader("content-disposition", "attachment; filename=export.json");
Context.Response.AddHeader("content-length", str.Length.ToString());
Context.Response.Flush();
Context.Response.Write(str);
}
Please note the return type of void (which means that your WDSL will be next to useless for this function). Returning anything will screw up the response that is being hand-built.
Asp.net web services are SOAP-based web services. They'll always return XML. The Ajax libraries came along and the ScriptMethod stuff was introduced, but it doesn't change the underlying concept of it.
There's a couple things you can do.
WebMethods are borderline obsolete with the introduction of WCF. You might consider migrating your web services to WCF, in which you'll have much greater control over the output format.
If you don't want to do that, you can manually serialize the result of your webservice calls into JSON, and the service will wrap that in a SOAP header. You would then need to strip out the SOAP stuff.
Here are two forums threads for your reference:
http://forums.asp.net/t/1118828.aspx
http://forums.asp.net/p/1054378/2338982.aspx#2338982
I have no clear idea. They say on concentrating on setting the content type to application/json. I haven't worked with wcf before, but I think you can make use of the Response object.
Set the content type on the response object. Do a response.write passing your json data as string and then do a response.end.
Just thought I'd throw this out there since it wasn't mentioned previously... if you use WebServices with ASP.NET 3.5, JSON is the default return format. It also comes along with JSON serializer so you can stop using the JavascriptSerializer.
This article on Rick Strahl's blog talks about the strongly-typed conversion you can do between server side classes and JSON objects from the client.
I've recently completed a project using this new JSON stuff in .NET 3.5, and I'm extremely impressed with the performance. Maybe it's worth a look...

Online JSONP converter/wrapper

I would like to fetch a source of file and wrap it within JSONP.
For example, I want to retrieve pets.txt as text from a host I don't own. I want to do that by using nothing but client-side JavaScript.
I'm looking for online service which can convert anything to JSONP.
YQL
Yahoo Query Language is one of them.
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D"http://elv1s.ru/x/pets.txt"&format=json&callback=grab
This works if URL is not blocked by robots.txt. YQL have respect to robots.txt. I can't fetch http://userscripts.org/scripts/source/62706.user.js because it blocked via robots.txt.
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D"http://userscripts.org/scripts/source/62706.user.js"&format=json&callback=grab
"forbidden":"robots.txt for the domain disallows crawling for url: http://userscripts.org/scripts/source/62706.user.js"
So I'm looking for another solutions.
I built jsonpwrapper.com.
It's unstable and slower than YQL, but it doesn't care about robots.txt.
Here's another one, much faster, built on DigitalOcean & CloudFlare, utilizing caching et al: http://json2jsonp.com
Nononono. No. Just please; no. That is not JSONP, it is javascript that executes a function with an object as its parameter that contains more javascript. Aaah!
This is JSON because it's just one object:
{
'one': 1,
'two': 2,
'three':3
}
This is JSONP because it's just one object passed through a function; if you go to http://somesite/get_some_object?jsonp=grab, the server will return:
grab({
'one': 1,
'two': 2,
'three':3
});
This is not JSON at all. It's just Javascript:
alert("hello");
And this? Javascript code stored inside a string (ouch!) inside an object passed to a function that should evaluate the string (but it might or might not):
grab({"body": "alert(\"Hello!\");\n"});
Look at all those semicolons and backslashes! I get nightmares from this kind of stuff. It's like a badly written Lisp macro because it's much more complicated than it needs to (and should!) be. Instead, define a function called grab in your code:
function grab(message) {
alert(message.body);
}
and then use JSONP to have the server return:
grab({body: "Hello!"});
Don't let the server decide how to run your web page Instead, let your web page decide how to run the web page and just have the server fill in the blanks.
As for an online service that does this? I don't know of any, sorry
I'm not sure what you're trying to do here, but nobody will use something like this. Nobody is going to trust your service to always execute as it should and output expected JavaScript code. You see Yahoo doing it because people trust Yahoo, but they will not trust you.