To Make an API Centric Application or Not? - Laravel - api

So. I have embarked on the journey of learning Laravel in the last couple of weeks, and am thoroughly enjoying it.
It has come time for a site redesign and I thought it was about time to tighten up some of our functionality, so I am making the switch from CodeIgniter to Laravel.
I was wondering whether it is worth starting off with a RESTful API layer in Laravel (easy enough to create) and use it as a base even for the web application. In the future we are likely to build a mobile app that will need to use the API. So:
Is it worth having the web application connect to the API
and what is the easiest way/s to make calls to the API without having to write a bazillion
lines for cURL everytime I want to make a request?

It is definitely worth it.
I am currently redesigning a messy PHP code for an established hosting company turning it into beautiful Laravel code. I already have a mobile app working with it - Laravel makes it easy to return JSON data with one line -
Response::json('OK', 200);
or
Response::eloquent(Auth::user());
or
$tasks = Task::all();
Response::eloquent($tasks);
You don't need to use CURL as far as I know.
You can make all requests with simple AJAX, jQuery would simplify that.
Also using some MVC JS framework would help you make the application code structure more elegant for the client side, and the advantage is that you can easily package that into PhoneGap when you are ready to have your API take some real testing.
Today I posted on my blog about a simple example that you can try to see if this approach is worth your time : http://maxoffsky.com/code-blog/login-to-laravel-web-application-from-phonegap-or-backbone/
Check it out and accept the answer if you think it's on the right track.

As always, your results may vary, but this is exactly what I'm going through at the moment. I'm migrating a large .Net site with this API architecture and I've decided to keep it for Laravel.
I personally decided for this because:
More scalable. I can setup api.domain.com and then add additional
boxes/vm/whatever as our traffic grows. In fact, you could load
balance just the api by "round robin" or multiple dns entries for
that domain.
Future proofing for new sites and apps. Sounds like you're in the
same situation. I can see an app or two being added in the next year
or so.
Lost cost. You'll already be laying out your controllers, so really
it can be just a matter of setting them to RESTful and making small
tweaks to accommodate.
To be fair, some counter points:
Possibly additional load time, from processing through the API, though this should be minimal.
Additional security items to consider if you'd like to lock things down to just your app.
Either way, welcome to Laravel!

and what is the easiest way/s to make calls to the API without having to write a bazillion lines for cURL everytime I want to make a request?
#Sneaksta try postman chrome extension for calling rest services. you can create forms in this extension and pass data from these forms to you Rest services
https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?utm_source=chrome-ntp-icon

Related

How to authenticate multiple api using Nuxt and nuxt-auth module

I have an application with (nuxt js using nuxt-auth) with local authentication so far (later I want to add git and google auth).
Now I need to add authentication to invoke other services / API (like google cloud rest API, payment system, youtube API, etc...)
The question is: the user is authenticated only once (during login to the application.) but each of these 3rd party APIs has its own authentication.
How to implement multiple authentications. (I read the documentation and google for the entire day but there is no clear answer).
As of today, it looks like it is not doable (people are needed on this module): https://github.com/nuxt-community/auth-module/issues/889
So, you would need to make it manually by plugging the APIs yourself.
Answer to your latest question~comment
Nuxt is indeed nice with some of it's modules (but you can totally dislike it, no problem :D).
First thing that you need to know, is that this project (nuxt-auth) is not the biggest one, #pooya is doing his best but he is on a lot of projects, so he cannot give all of his love to it. Then, you also need to understand that it's working great but it's still in a decent beta state with a lot of missing features, needed documentation and a lot of small things to make it an all rounded solid top notch solution.
That do not mean that you should not use it, I'm just saying that this module do have some limitations. Hence, the fact that it is not supporting a whole lot of OAuth solutions in a clear + simple + flexible way. And some breaking changes may be introduced in future updates.
The module is aimed towards having an OAuth solution to block the content of your website behind it (in my opinion). It means that you will usually use a single login solution and then, being able to have access to your app. I don't think that it's a viable multi-OAuth solution (yet).
Some services don't even need to use a solution like this. Stripe for example, should not be handled on the frontend but communicate with a backend for sensitive variables and just send minimal info thanks to Stripe Elements.
That said, the most common solution is JWT or OAuth2, and you could totally have a backend service or service like Okta, Auth0 or alike, do the heavy lifting by allowing simple logins to providers (Github, Google etc...).
To sum up, you do connect to this backend/service thanks to nuxt-auth, the service itself does the provider connection and you get the best of both worlds while still connected in a secure way through your initial nuxt-auth entry point login.
Or you could try to reach the community on Discord, see if somebody knows how to do it. Or even try to read the source code to see if it is currently feasable.
And that's my 2cts.

What pitfalls or consequences could there be when structuring a solution in 3 projects (.net core, vue.js and webapi)?

I want to make a quick, safe and nice application.
For many years I have been programming in PHP and regular ASP. But wanted to go on with .NET and vue.js.
So I have an idea, I wanted to create and plan to do it like this:
I was thinking of using hosting from an external service.
Then I would have three projects:
domain.com/index - Vue.js which will be a SPA, where the user can filter through a catalog, press like and send few api requests (mainly get-requests).
secure.domain.com - Here I will have a .net mvc project where I can use identity. This will make it simple to handle/register users. I will also give the correct session here for authenticated users. And it will affect domain.com/index, where they only are allowed to do some of the things if they are logged in
api.domain.com - This will be the webapi api. Only authenticated users will be allowed to send some of the requests.
I have used several weeks at looking into how to structure this.
But as I do not have much experience with this.
What pitfalls and bad consequences do you see in structuring it like this?
Are there any heads up you want to give me? Or any other recommendations?
I have been trying to melt all of this together in one project, but that has been difficult, because they operate in different ways. So now I have ended up with this, and look forward to
Size of project
It will be a relative small project.
People should be able to register/authenticate themselves (through facebook/google/server login).
Authenticated People should be able to add records(links) to a database. When adding this to the database they may also want to upload files, and choose some additional information.
All people should be able to filter through the catalog of records (5000+) ( Here I am using vue.js/vuex/axios). Here they should be able to comment too on links too.
Webapi will have 8 entities/tables and one view which will GET all the information. 3 tables should be able to have POST.
So it is more or less a catalog, where people should be able to add records and find new ones.
I was planning to use the identity from asp.net core 3.1. It is a "template" where I can easily add 3rd party logins. (https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-3.1&tabs=visual-studio)
Additional questions:
Can you tell me how request from SPA will be authenticated in your API? (Jwt or cookie)? Why would you like to have a separate identity service, also Why you would like to use asp.net identity (is it because of ease of setup)?
I have not been thinking about authenticating API requests. Was thinking to only have authenticated users who can send POST-requests. And the rest will be get requests. Limited only from the server. Should I have some additional authentication? Does JWT make web APIs safe enough for my use?
Was thinking of using .net identity because it is simple. And I don't want to use time on setting it up.
Since this is your first project of this type, I would recommend to keep it simple.
Just create one web site. Otherwise you might get issues with the cookies not working for subdomains and you will also get issues with CORS. That is, you will get all problems at the same to time (configuration issues, infrastructure issues and the pain from writing the application itself).
You can still have a clean separation by using sub folders (or Areas in MVC) and by using class libraries for the backend (API) business logic.
Once you have mastered the basics (i.e. writing the actual application) you can start looking at other means of separation etc.

What is the point of using /api/v1/(whatever route here) in express?

Ive been making API's for about a year now and I was taught to use http://IPAddress:Port/api/v1 all the time when building an API with express.js. Is there a specific reason I would want to do that? Is this just denoting that the API is in development? Ive recently changed my API to not run on port 3000 so that I am able to just say http://IPAddress.com/ instead of http://IPAddress.com:3000/api/v1 and it works just fine the new way.
One main reason for versioning an API is because it may be that an API can be improved upon but doing so might lead to breaking changes (for example, it might not work for applications that are consuming the API because an endpoint has been modified).
So, the solution to this is to allow consumers of the current API (v1) to keep using it until they want to switch, and release an updated version (v2) for new consumers.
Here's some more info on it: https://restfulapi.net/versioning/

Is it necessary to build a separate API endpoint for mobile apps to access a Rails web app?

I have a web app implemented in Ruby on Rails 4, need an Android native app for it, I am really new to mobile development.
I am a bit confused as to what the mobile-web architecture should look like in this case. I've done some research online, there seems to be a few ways of doing this, but I still have some questions that I haven't been able to find answers for. Thanks in advance for all pointers.
1) do I really need a separate API for the mobile app? what are the issues in using my Rails app's existing controllers with respond_to format.json?
2) I've seen some online examples that suggest using an separate API namespace in the Rails app to serve mobile requests, e.g class Api::ApiController < ActionController::Base for the new controller, then add namespace :api do in routes.rb. With this approach, doesn't it imply that I'll need to duplicate quite a bit of my controller functionality in this new namespace just for mobile?
3) Regarding authentication, many examples suggest using token authentication, is the built-in Rails sessions management framework not good enough for mobile apps? or is it because session cookies work completely differently in a mobile app?
Appreciate your time.
It is not necessary, but it is, like you said, considered a best practice.
1+2) Having same controllers with respond_to/respond_with logic is a nice idea at first sight. But, from my experience, I can say, there always comes a day where API code start to differ with HTML client code. The mobile client might have a different UI and it is just natural that it will expect to consume your data another way as your web client does. The web client is specialized to one use case where an API should be more generic allowing multiple consuming ways.
The second issue that will arise is the fact that you cannot rely on your mobile users to always have the latest app version where with a webapp you can. So for the HTML app you can easily introduce non-compatible changes because you are delivering a proper client right within where for the mobile API breaking the API is at least concerning. Perhaps, you will want to maintain a backwards compatibility which will make your all purpose controllers ugly as hell. And without a proper api/v1 namespace you even can't have two different API versions at the same time.
You can avoid duplication of your logic by keeping your controllers very skinny and move the logic out into models (Service Objects are models too, not only Active Records).
3) Your mobile HTTP lib will to a high probability have a proper automatic cookie management. Having token based authentication is just again a best practice. If it is just a token vs session_id within cookie, there will be not much win. I can only think that it will be automatically secure against CSRF attack and you can disable this protection entirely for the API because your website users won't be allowed to consume the API, just by logging in to the site (an additional benefit perhaps). With session based authentication you will have to generate a CSRF token on first API request and set it within X-CSRF-Token cookie.
The big advantage of token based authentication is that it is extendable to more security, like introducing expire tokens, HMAC tokens etc, whereby session authentication is not.
See Using Sessions vs Tokens for API authentication
I would also encourage you to look at json:api. It comes from the creators of ember.js, who have thought about minifying decisions to take, when building APIs. Another interesting thing is an active_model_serializers gem. An intro to it is given within Rails: The Next Five Years by Yehuda Katz

Separate REST JSON API server and client? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I'm about to create a bunch of web apps from scratch. (See http://50pop.com/code for overview.) I'd like for them to be able to be accessed from many different clients: front-end websites, smartphone apps, backend webservices, etc. So I really want a JSON REST API for each one.
Also, I prefer working on the back-end, so I daydream of me keeping my focus purely on the API, and hiring someone else to make the front-end UI, whether a website, iPhone, Android, or other app.
Please help me decide which approach I should take:
TOGETHER IN RAILS
Make a very standard Rails web-app. In the controller, do the respond_with switch, to serve either JSON or HTML. The JSON response is then my API.
Pro: Lots of precedent. Great standards & many examples of doing things this way.
Con: Don't necessarily want API to be same as web app. Don't like if/then respond_with switch approach. Mixing two very different things (UI + API).
REST SERVER + JAVASCRIPT-HEAVY CLIENT
Make a JSON-only REST API server. Use Backbone or Ember.js for client-side JavaScript to access API directly, displaying templates in browser.
Pro: I love the separation of API & client. Smart people say this is the way to go. Great in theory. Seems cutting-edge and exciting.
Con: Not much precedent. Not many examples of this done well. Public examples (twitter.com) feel sluggish & are even switching away from this approach.
REST SERVER + SERVER-SIDE HTML CLIENT
Make a JSON-only REST API server. Make a basic HTML website client, that accesses the REST API only. Less client-side JavaScript.
Pro: I love the separation of API & client. But serving plain HTML5 is quite foolproof & not client-intensive.
Con: Not much precedent. Not many examples of this done well. Frameworks don't support this as well. Not sure how to approach it.
Especially looking for advice from experience, not just in-theory.
At Boundless, we've gone deep with option #2 and rolled it out to thousands of students. Our server is a JSON REST API (Scala + MongoDB), and all of our client code is served straight out of CloudFront (ie: www.boundless.com is just an alias for CloudFront).
Pros:
Cutting-edge/exciting
A lot of bang for your buck: API gives you basis for your own web client, mobile clients, 3rd party access, etc.
exceedingly fast site loading / page transitions
Cons:
Not SEO friendly/ready without a lot more work.
Requires top-notch web front-end folk who are ready to cope w/ the reality of a site experience that is 70% javascript and what that means.
I do think this is the future of all web-apps.
Some thoughts for the web front end folks (which is where all the new-ness/challenge is given this architecture):
CoffeeScript. Much easier to produce high-quality code.
Backbone. Great way to organize your logic, and active community.
HAMLC. Haml + CoffeeScript templates => JS.
SASS
We've built a harness for our front-end development called 'Spar' (Single Page App Rocketship) which is effectively the asset pipeline from Rails tuned for single page app development. We'll be open-sourcing within the next couple of weeks on our github page, along with a blog post explaining how to use it and overall architecture in greater detail.
UPDATE:
With respect to people's concerns with Backbone, I think they are over-rated. Backbone is far more an organizational principle than it is a deep framework. Twitter's site itself is a giant beast of Javascript covering every corner-case across millions of users & legacy browsers, while loading tweets real-time, garbage collect, display lots of multimedia, etc. Of all the 'pure' js sites I've seen, Twitter is the odd one out. There have been many impressively complicated apps delivered via JS that fare very well.
And your choice of architecture depends entirely on your goals. If you are looking for the fastest way to support multiple clients and have access to good front-end talent, investing in a standalone API is a great way to go.
Very well asked. +1. For sure, this is future useful reference for me. Also #Aaron and others added value to discussion.
Like Ruby, this question is equally applicable to other programming environments.
I have used the first two options. First one for numerous applications and second one for my open source project Cowoop
Option 1
This one is no doubt the most popular one. But I find implementation are very much http-ish. Every API's initial code goes in dealing with request object. So API code is more than pure ruby/python/other language code.
Option 2
I always loved this.
This option also implies that HTML is not runtime generated on server. This is how option 2 is different from option 3. But are build as static html using a build script. When loaded on client side these HTML would call API server as JS API client.
Separation of concerns is great advantage. And very much to your liking (and mine) backend experts implement backend APIs, test them easily like usual language code without worrying about framework/ http request code.
This really is not as difficult as it sounds on frontend side. Do API calls and resulting data (mostly json) is available to your client side template or MVC.
Less server side processing. It means you may go for commodity hardware/ less expensive server.
Easier to test layers independently, easier to generate API docs.
It does have some downsides.
Many developers find this over engineered and hard to understand. So chances are that architecture may get criticized.
i18n/l10n is hard. Since HTML is essentially generated build time are static, one needs multiple builds per supported language (which isn't necessarily a bad thing). But even with that you may have corner cases around l10n/i18n and need to be careful.
Option 3
Backend coding in this case must be same as second option. Most points for option 2 are applicable here as well.
Web pages are rendered runtime using server side templates. This makes i18n/l10n much easier with more established/accepted techniques. May be one less http call for some essential context needed for page rendering like user, language, currency etc. So server side processing is increased with rendering but possibly compensated by less http calls to API server.
Now that pages are server rendered on server, frontend is now more tied with programming environment. This might not be even a consideration for many applications.
Twitter case
As I understand, Twitter might does their initial page rendering on server but for page updates it still has some API calls and client side templates to manipulate DOM. So in such case you have double templates to maintain which adds some overhead and complexity. Not everyone can afford this option, unlike Twitter.
Our project Stack
I happen to use Python. I use JsonRPC 2.0 instead of REST. I suggest REST, though I like idea of JsonRPC for various reasons. I use below libraries. Somebody considering option 2/3 might find it useful.
API Server: Python A fast web micro framework - Flask
Frontend server: Nginx
Client side MVC: Knockout.js
Other relevant tools/libs:
Jquery
Accounting.js for money currency
Webshim : Cross browser polyfill
director: Client side routing
sphc: HTML generation
My conclusion and recommendation
Option 3!.
All said, I have used option 2 successfully but now leaning towards option 3 for some simplicity. Generating static HTML pages with build script and serving them with one of ultra fast server that specialize in serving static pages is very tempting (Option 2).
We opted for #2 when building gaug.es. I worked on the API (ruby, sinatra, etc.) and my business partner, Steve Smith, worked on the front-end (javascript client).
Pros:
Move quickly in parallel. If I worked ahead of Steve, I could keep creating APIs for new features. If he worked ahead of me, he could fake out the API very easily and build the UI.
API for free. Having open access to the data in your app is quickly becoming a standard feature. If you start with an API from the ground up, you get this for free.
Clean separation. It is better to think of your app as an API with clients. Sure, the first and most important client may be a web one, but it sets you up for easily creating other clients (iPhone, Android).
Cons:
Backwards Compatibility. This is more related to an API than your direct question, but once your API is out there, you can't just break it or you break all your clients two. This doesn't mean you have to move slower, but it does mean you have to often make two things work at once. Adding on to the API or new fields is fine, but changing/removing shouldn't be done without versioning.
I can't think of anymore cons right now.
Conclusion: API + JS client is the way to go if you plan on releasing an API.
P.S. I would also recommend fully documenting your API before releasing it. The process of documenting Gaug.es API really helped us imp
http://get.gaug.es/documentation/api/
I prefer to go the route of #2 and #3. Mainly because #1 violates separation of concerns and intermingles all kinds of stuff. Eventually you'll find the need to have an API end point that does not have a matching HTML page/etc and you'll be up a creek with intermingled HTML and JSON endpoints in the same code base. It turns into a freaking mess, even if its MVP, you'll have to re-write it eventually because its soo messy that its not even worth salvaging.
Going with #2 or #3 allows you to completely have a API that acts the same (for the most part) regardless. This provides great flexibility. I'm not 100% sold on Backbone/ember/whatever/etc.js just yet. I think its great, but as we're seeing with twitter this is not optimal. BUT... Twitter is also a huge beast of a company and has hundreds of millions of users. So any improvement can have a huge impact to bottom line on various areas of various business units. I think there is more to the decision than speed alone and they're not letting us in on that. But thats just my opinion. However, I do not discount backbone and its competitors. These apps are great to use and are very clean and are very responsive (for the most part).
The third option has some valid allure as well. This is where I'd follow the Pareto principle (80/20 rule) and have 20% of your main markup (or vice versa) rendered on the server and then have a nice JS client (backbone/etc) run the rest of it. You may not be communicating 100% with the REST api via the JS client, but you will be doing some work if necessary to make the suer experience better.
I think this is one of those "it depends" kinds of problems and the answer is "it depends" on what you're doing, whom you're serving and what kind of experience you want them to receive. Given that I think you can decide between 2 or 3 or a hybrid of them.
I'm currently working on converting a huge CMS from option 1 to option 3, and it's going well. We chose to render the markup server-side because SEO is a big deal to us, and we want the sites to perform well on mobile phones.
I'm using node.js for the client's back-end and a handful of modules to help me out. I'm somewhat early in the process but the foundation is set and it's a matter of going over the data ensuring it all renders right. Here's what I'm using:
Express for the app's foundation.
(https://github.com/visionmedia/express)
Request to fetch the data.
(https://github.com/mikeal/request)
Underscore templates that get rendered server side. I reuse these on the client.
(https://github.com/documentcloud/underscore)
UTML wraps underscore's templates to make them work with Express.
(https://github.com/mikefrey/utml)
Upfront collects templates and let's you chose which get sent to the client.
(https://github.com/mrDarcyMurphy/upfront)
Express Expose passes the fetched data, some modules, and templates to the front-end.
(https://github.com/visionmedia/express-expose)
Backbone creates models and views on the front-end after swallowing the data that got passed along.
(https://github.com/documentcloud/backbone)
That's the core of the stack. Some other modules I've found helpful:
fleck (https//github.com/trek/fleck)
moment (https//github.com/timrwood/moment)
stylus (https//github.com/LearnBoost/stylus)
smoosh (https//github.com/fat/smoosh)
…though I'm looking into grunt (https//github.com/cowboy/grunt)
console trace (//github.com/LearnBoost/console-trace).
No, I'm not using coffeescript.
This option is working really well for me. The models on the back-end are non-existant because the data we get from the API is well structured and I'm passing it verbatim to the front-end. The only exception is our layout model where I add a single attribute that makes rendering smarter and lighter. I didn't use any fancy model library for that, just a function that adds what I need on initialization and returns itself.
(sorry for the weird links, I'm too much of a n00b for stack overflow to let me post that many)
We use the following variant of #3:
Make a JSON-only REST API server. Make an HTML website server. The HTML web server is not, as in your variant, a client to the REST API server. Instead, the two are peers. Not far below the surface, there is an internal API that provides the functionality that the two servers need.
We're not aware of any precedent, so it's kind of experimental. So far (about to enter beta), it has worked out pretty well.
I'm usually going for the 2nd option, using Rails to build the API, and backbone for the JS stuff. You can even get an admin panel for free using ActiveAdmin.
I've shipped tens of mobile apps with this kind of backend.
However it heavily depends if your app is interactive or not.
I did a presentation on this approach at the last RubyDay.it: http://www.slideshare.net/matteocollina/enter-the-app-era-with-ruby-on-rails-rubyday
For the third option, in order to get responsiveness of the 2nd one, you might want to try pajax as Github does.
I'm about 2 months into a 3 month project which takes the second approach you've outlined here. We use a RESTful API server side with backbone.js on the front. Handlebars.js manages the templates and jQuery handles the AJAX and DOM manipulation. For older browsers and search spiders we've fallen back onto server side rendering, but we're using the same HTML templates as the Handlebars frontend using Mozilla Rhino.
We chose this approach for many different reasons but are very aware it's a little risky given it hasn't been proven on a wide scale yet. All te same, everything's going pretty smoothly so far.
So far we've just been working with one API, but in the next phase of the project we'll be working with a second API. The first is for large amounts of data, and the second acts more like a CMS via an API.
Having these two pieces of the project act completely independent of each other was a key consideration in selecting this infrastructure. If you're looking for an architecture to mashup different independent resources without any dependencies then this is approach is worth a look.
I'm afraid I'm not a Ruby guy so I can't comment on the other approaches. Sometimes it's okay to take a risk. Other times it's better to play it safe. You'll k ow yourself depending on the type of project.
Best of luck with your choice here. Keen to see what others share as well.
I like #3 when my website is not going to be a 100% CRUD implementation of my data. Which is yet to happen.
I prefer sinatra and will just split up the app into a few different rack apps with different purposes. I'll make an API specific rack app that will cover what I need for the API. Then perhaps a user rack app that will present my webpage. Sometimes that version will query the API if needed, but usually it just concerns itself with the html site.
I don't worry about it and just do a persistance layer query from the user side if I need it. I'm not overly concerned with creating a complete separation as they usually end up serving different purposes.
Here is a very simple example of using multiple rack apps. I added a quick jquery example in there for you to see it hitting the API app. You can see how simple it can be with sinatra and mounting multiple rack apps with different purposes.
https://github.com/dusty/multi-rack-app-app
Some great answers here already - I'd definitely recommend #2 or #3 - the separation is good conceptually but also in practice.
It can be hard to predict things like load and traffic patterns on an API and customers we see who serve the API independently have an easier time of provisioning and scaling. If you have to do that munged in with human web access patterns it's less easy. Also your API usage might end up scaling up a lot faster than your web client and then you can see where to direct your efforts.
Between #2 #3 it really depends on your goals - I'd agree that #2 is probably the future of webapps - but maybe you want something more straightforward if that channel is only going to be one of many!
For atyourservice.com.cy we are using server side rendered templates for pages especially to cover the se part. And using the API for interactions after page loads.
Since our framework is MVC all controller functions are duplicated to json output and html output. Templates are clean and receive just an object. This can be transformed to js templates in seconds. We always maintain the serverside templates and just reconvert to js on request.
Isomorphic rendering and progressive enhancement. Which is what I think you were headed for in option three.
isomorphic rendering means using the same template to generate markup server-side as you use in the client side code. Pick a templating language with good server-side and client-side implementations. Create fully baked html for your users and send it down the wire. Use caching too.
progressive enhancement means start doing client side execution and rendering and event listening once you've got all the resources downloaded and you can determine a client capabilities. Falling back to functional client-script-less functionality wherever possible for accessibility and backwards compatibility.
Yes, of course write a standalone json api for this app functionality. But don't go so far that you write a json api for things that work fine as static html documents.
REST server + JavaScript-heavy client was the principle I've followed in my recent work.
REST server was implemented in node.js + Express + MongoDB (very good writing performance) + Mongoose ODM (great for modelling data, validations included) + CoffeeScript (I'd go ES2015 now instead) which worked well for me. Node.js might be relatively young compared to other possible server-side technologies, but it made it possible for me to write solid API with payments integrated.
I've used Ember.js as JavaScript framework and most of the application logic was executed in the browser. I've used SASS (SCSS specifically) for CSS pre-processing.
Ember is mature framework backed by strong community. It is very powerful framework with lots of work being done recently focused on performance, like brand new Glimmer rendering engine (inspired by React).
Ember Core Team is in process of developing FastBoot, which let's you to execute your JavaScript Ember logic on server-side (node.js specifically) and send pre-rendered HTML of your application (which would normally be run in browser) to user. It is great for SEO and user experience as he doesn't wait so long for page to be displayed.
Ember CLI is great tool that helps you to organise your code and it did well to scale with growing codebase. Ember has also it's own addon ecosystem and you can choose from variety of Ember Addons. You can easily grab Bootstrap (in my case) or Foundation and add it to your app.
Not to serve everything via Express, I've chosen to use nginx for serving images and JavaScript-heavy client. Using nginx proxy was helpful in my case:
upstream app_appName.com {
# replace 0.0.0.0 with your IP address and 1000 with your port of node HTTP server
server 0.0.0.0:1000;
keepalive 8;
}
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
client_max_body_size 32M;
access_log /var/log/nginx/appName.access.log;
error_log /var/log/nginx/appName.error.log;
server_name appName.com appName;
location / {
# frontend assets path
root /var/www/html;
index index.html;
# to handle Ember routing
try_files $uri $uri/ /index.html?/$request_uri;
}
location /i/ {
alias /var/i/img/;
}
location /api/v1/ {
proxy_pass http://app_appName.com;
proxy_next_upstream error timeout invalid_header http_500 http_502
http_503 http_504;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Pro: I love the separation of API & client. Smart people say this is
the way to go. Great in theory. Seems cutting-edge and exciting.
I can say it's also great in practice. Another advantage of separating REST API is that you can re-use it later for another applications. In perfect world you should be able to use the same REST API not only for webpage, but also for mobile applications if you'd decide to write one.
Con: Not much precedent. Not many examples of this done well. Public
examples (twitter.com) feel sluggish & are even switching away from
this approach.
Things look different now. There are lots of examples of doing REST API + many clients consuming it.
I decided to go for the architecture of Option #2 for Infiniforms, as it provided a great way to separate the UI from the business logic.
An advantage of this is that the API Servers can scale independently of the web servers. If you have multiple clients, then the websites will not need to scale to the same extent as the web servers, as some client swill be phone / tablet or desktop based.
This approach also gives you a good base for opening up your API to your users, especially if you use your own API to provide all of the functionality for your website.
A very nice question and I'm surprised as I thought this is a very common task nowadays such that I will have plenty of resources for this problem, however turned out not to be true.
My thoughts are as follows:
- Create some module that have the common logic between the API controllers and HTML controllers without returning json or rendering html, and include this module in both HTML controller and API controller, then do whatever you want, so for example:
module WebAndAPICommon
module Products
def index
#products = # do some logic here that will set #products variable
end
end
end
class ProductsController < ApplicationController
# default products controlelr, for rendering HMTL pages
include WebAndAPICommon
def index
super
end
end
module API
class ProductsController
include WebAndAPICommon
def index
super
render json: #products
end
end
end
I've gone for a hybrid approach where we user Sinatra as a base, ActiveRecord / Postgress etc to serve up page routes (slim templates) expose a REST API the web-app can use. In early development stuff like populating select options is done via helpers rendering into the slim template, but as we approach production this gets swapped out for an AJAX call to a REST API as we start to care more about page-load speeds and so forth.
Stuff that's easy to render out in Slim gets handled that way, and stuff (populating forms, receiving form POST data from jQuery.Validation's submitHandler etc, is all abviously AJAX)
Testing is an issue. Right now I'm stumped trying to pass JSON data to a Rack::Test POST test.
I personally prefer option (3) as a solution. It's used in just about all the sites a former (household name) employer of mine has. It means that you can get some front-end devs who know all about Javascript, browser quirks and whatnot to code up your front end. They only need to know "curl xyz and you'll get some json" and off they go.
Meanwhile, your heavy-weight back-end guys can code up the Json providers. These guys don't need to think about presentation at all, and instead worry about flaky backends, timeouts, graceful error handling, database connection pools, threading, and scaling etc.
Option 3 gives you a good, solid three tier architecture. It means the stuff you spit out of the front end is SEO friendly, can be made to work with old or new browsers (and those with JS turned off), and could still be Javascript client-side templating if you want (so you could do things like handle old browsers/googlebot with static HTML, but send JS built dynamic experiences to people using the latest Chrome browser or whatever).
In all the cases I've seen Option 3, it's been a custom implementation of some PHP that isn't especially transferable between projects, let alone out in to Open Source land. I guess more recently PHP may have been replaced with Ruby/Rails, but the same sort of thing is still true.
FWIW, $current_employer could do with Option 3 in a couple of important places. I'm looking for a good Ruby framework in which to build something. I'm sure I can glue together a load of gems, but I'd prefer a single product that broadly provides a templating, 'curling', optional-authentication, optional memcache/nosql connected caching solution. There I'm failing to find anything coherent :-(
Building a JSON API in Rails is first class, The JSONAPI::Resources gem does the heavy lifting for a http://jsonapi.org spec'd API.