API + SPA Deployment Best Practices - laravel

Developing a SPA in the frontend (with Vue.js) which consumes endpoints from a (Laravel) API in the backend introduces some challenges that need to be tackled:
1. How to sync deployment when introducing new backend/frontend code
If the code is separated in two VCS repositories (frontend/backend) it can be challenging to sync deployment of both frontend and backend making sure that both finish at the exact same time. Otherwise this can lead to unexpected behaviour (e.g. calling endpoints that are not yet deployed or have changed). Anyone came up with a great solution for this? What is your best practice to tackle this problem? What if versioning every little change is not an option?
2. How to make sure that the frontend code of the SPA is being refreshed after deployment?
So you managed to keep your deployments in sync (see problem 1.), but how do you make sure that the SPA code of every currently active end user is being refreshed? With webpack code splitting enabled, the application might break immediately for users that are currently using your app in between a deployment.
How do you make sure that your users are being served the latest JS without having them reload the entire application on every request? What are best practices (besides forcing the user to refresh the entire page via websockets)? Are there solutions that allow currently active users to keep using the application without being forced to refresh while they might just finished something that's ready to be saved?
I am very interested in your findings, learnings and solutions!

1. How to sync deployment when introducing new backend/frontend code
The best practice here is to keep the backend and frontend in the same repo. You can, of course, extract some reusable code out of them to use in other projects but the code base should ideally be in the same repo or you will keep facing these frustrating code sync issues. Even if you look at popular Laravel libraries - they all have the frontend and backend in the same repo.
If that's not option, I would suggest that you use a versioning system that can link the versions of both repos. Yep, that means versioning every little change!
2. How to make sure that the frontend code of the SPA is being refreshed after deployment?
Usually, I'd avoid doing stuff to force a refresh on the client codebase but if you have long user sessions, it may actually make sense.
To do that, you can use any web socket implementation (such as Pusher) and have your CI notify the frontend through web sockets of any deployment. The frontend can then queue a page refresh. Check out this article on how to implement.

The two questions are tightly coupled and can't be answered separately in my opinion. I have some possibile strategies to deal with such a scenario:
1. Never introduce breaking changes in the API
API deployments should be incremental without breaking anything for users using the previous version. In this way you can simply push the changes on your backend and when the backend deployment is completed you deploy the frontend. Easily achieved if you have separate projects.
This can be performed for major releases by prefixing the API with the version:
https://website.url/api/v${version}/${endpoint}
while minor deployments should only be minor adjustments/bugfixes that do not break frontend functionality.
This approach is the best because it ensures absolutely no downtime in the user activity, but requires additional work and may not be feasible in many projects. If the backend does not introduce breaking changes, you can implement a simple polling system (with a long timespan, such as minutes) from the frontend that detects if a reload in necessary to load the new frontend deployment.
2. Standard response for outdated requests
Each request from the frontend includes an information about the version in use by the frontend. It could be a standard header, a param, whatever. You should wrap your requests in a function that add the information before sending the request itself.
If the server detects a request from an outdated frontend, it returns a standard response, such as:
{
"error": "update required"
}
The frontend detects the error and reload the page
I honestly don't like this approach, because the request may be a POST request with some form data and a page reload may lose the user all their input, which is annoying.

1. How to sync deployment when introducing new backend/frontend code
With a staging environment where you run both test suites before pulling on production.
2. How to make sure that the frontend code of the SPA is being refreshed after deployment?
Don't just break your API. Implement a grace period. For example, you could check for updates on every request, then notify the user that a new version is available so that they have to click a button at their earliest convenience. Record the used client version in your DB. Once all your users are updated, you can delete the old endpoints.

Related

How to set up authorization using js-SSR and SPA?

I want to develop my own single page web application (SPA) to get to grips with the modern and highly fluid world of web development. At the same time, I would like to use the page rendering technology (SSR) with built in data into html. However, there is an authorization problem.
Suppose that the user has already logged into the account before, as I imagine re-opening the site:
First request: the client makes a request to the frontend server along with identification and authorization data (for example, user id and token; the only option is to save them in cookies), the frontend server makes a request to the api server, transferring these service data, then the api server gives the information about the user and the content of the current page (in the same json), the frontend server renders this into a finished page and delivers it to the client.
Subsequent requests: the client directly addresses the api server, transferring the same (or updated after the first request) authorization data, receives json and processes it independently.
Actually, I want to move on to the question. Do I understand this interaction correctly? Can you do it differently / better? Are there tools that allow, for example, to use the components of the frontend framework as components of the MVC backend framework, so that one server does the rendering without unnecessary requests? Or a unified tool that includes the same coding for the frontend and backend to solve these problems? I will say right away that I would not like to write a backend in JS.
I can roughly imagine how you can get by with one request when using AngularJS (with a module for single page applications) and any backend MVC framework; although there will not be a full-fledged render, but search robots will not have to wait for my first fetch, since the data will be delivered initially, for example, through the data attribute. But in this case, I plan to choose Svelte (Sapper) and Ruby on Rails as the stack, although I think this is not important.
Thank you for your attention to the question!
Are there tools that allow, for example, to use the components of the frontend framework as components of the MVC backend framework, so that one server does the rendering without unnecessary requests?
If that's what you want you can install a frontend framework in Rails using webpacker. After that you will have a folder in your rails project that will contain your Svelte components. Then you import Svelte components in erb templates and pass data as props.
I have tried that approach but personally I prefer a separate frontend and backend talking through API calls. Then in your frontend you need something like Sapper if you need SSR. With webpacker you don't(assuming you mostly use Rails for routing).
If you are worried about authorization it's not really hard to implement. And after login you can store user info on local storage for instance for subsequent requests. But of course if you install with webpacker it's all done within Rails hence it's easier.
From my experience, using webpacker it's easy and quick in the beginning but you are more likely to get headaches in the future. With separate backend and frontend takes a bit more work, especially in the beginning, but it's smoother in the long run.
This helped me set the authentication between rails api and vue frontend.
So, if you wish to separate them, just install Rails as API only and I suggest you to use Jbuilder to build your jsons and serve them to the frontend as you need them.

How to detect and refresh outdated data in React Native app with redux-persist

In a React Native app, usingRedux and Redux-Persist, what is the best way to identify what content needs to be updated?
I have an app that does a few requests at startup.
When I enabled redux-persist I started to avoid a request if it was already done at another time. But I have no idea how best to identify whether or not to make the request again to update the data stored by redux-persist.
I read about the use of ETags andLast-Modified, but this implies implementing this in the API also right?
Any guidance for this functionality implemented in the right way?
Yes, you also need to update your API.
Another solution is to use push notifications to notify that the data changed and perform a new request every time the notification is received. But this also means implementing some code on server side.
You need a way to know that the data changed, for that reason you always need to implement some code in server side.

How to implement the following scenario using Jmeter?

Can anyone help me out how to implement the following scenario using Jmeter, in this scenario N number of users should be able to log in at once and implement the same scenario at the same time?
I have already tried using recording option but it is not updating in the database.
To some HTTP requests, it is showing SSO issue.
Steps:
1. Login to the web application.
2. A landing page is displayed.
3. Two options displayed.
4. Selecting one option, which will redirect to the specific landing page.
5. From home page, we will search for the products.
6. Selecting one product and it redirects to the customization page.
7. In the customization page, we are inputting the values, updating the changes to the order.
8. Finally completing the order with update changes in it.
Where the customize order will ask us to move into the cart or it will ask us to submit for approval.
The solution basically depends on what you exactly testing.
Let's consider the application consists of single HTTP server (at least, in terms of endpoint) + single HTTP client (which doesn't reach different sources for data/services, especially with modern protocols like websocket).
Then each of your scenarios turns out to be a series of HTTP request/response interactions, whatever happens under the hood.
So the best way to lay it out for JMeter would be to record sample(s) of this interaction & parametrize it.
You can do it with JMeter itself (check, for example, this guideline or "official" one), or use other tools (like Fiddler) then implement the sequence in the JMeter.
But that is for more, say, "classic" web app, where client (browser) are pretty lightweight and mostly in charge of sending requests & rendering responses - while most of the duties lays on server, and this is that you going to test for performance.
For modern, web apps with responsibilities blurred & spread between server AND client (not to mention asyncronous interactions) that way may be good enough too - but may be NOT.
Then you'd may want to evaluate performance for app as a whole, in assembly.
One of the way to achieve that in JMeter is to use WebDriver plugin for JMeter, check this tutorial.

Building A Social Network

So, I'm starting out building a social network web app. I'm looking into how to fit the parts of my stack together and I'm looking for some guidance about what various frameworks will allow me to do. My current stack idea is to have:
Firebase JSON API: serving user, post, comment, and all the other data
EmberFire: to plug that API into EmberJS
EmberJS: my front-end MVC (because I'm new to MVC and Ember seems the most accessible)
What I'm stumbling on at the moment is how I'm going to implement users with this stack. I've looked at basic authentication stuff but I haven't found anything that would allow me to allow certain actions and views for certain users and not others - the basics of a social network really.
Is it sensible to be doing this stuff in front-end MVC? If so what should I be using to do authentication/personalisation? If not, should I just be doing a PHP/SQL setup? I'd rather avoid that because my skills are all front-end.
If you are just getting started, Firebase is a great service to learn on due to their 'back end as a service' model - you will spend more time building/modeling your data and less time running/installing. Not that you won't want to learn more about that later, but it lets you focus on one piece at a time.
From an access perspective, JS/NoSQL vs PHP/MySQL isn't going to be the issue. They each have their own security requirements - it's more that PHP/MySQL has had more time to establish those rules. Additionally, Firebase being a hosted service has it's own set of requirements.
Firebase security rules are a little weird when you first look at them, but they begin to make some sense after you sit with them for a bit. The Firebase docs are actually a pretty great resource. https://www.firebase.com/docs/security/
Basically, if you use a Firebase 'login provider' it makes Firebase act as both a database and a authentication manager, and the combo helps keep users 'fenced' to where you want them. You can use data from other paths, variables, validation rules, etc. You can even make a 'custom login provider' if you need to integrate with an existing one.
Finally, on the client end, your view can respond to whatever Firebase returns - if a user does 'hack' their way through to a page they shouldn't be on client side, no data is returned anyways and no submitted information would be allowed because of the rules.

Should I do API requests server side or client side?

I am trying to make a web app using ExpressJS and Coffeescript that pulls data from Amazon, LastFM, and Bing's web API's.
Users can request data such as the prices for a specific album from a specific band, upcoming concert times and locations for a band, etc... stuff like that.
My question is: should I make these API calls client-side using jQuery and getJSON or should they be server-side? I've done client-side requests; how would I even make an API call from the server side?
I just want to know what the best practice is, and also if someone could point me in the right direction for making server-side API requests, that would be very helpful.
Thanks!
There's are two key considerations for this question:
Do calls incur any data access? Are the results just going to be written to the screen?
How & where do you plan to handle errors? How do you handle throttling?
Item #2 is really important here because web services go down all of the time for a whole host of reasons. Your calls to Bing, Amazon & Last FM will fail probably 1% or 0.1% of the time (based on my experiences here).
To make requests users server-side JS you probably want to take a look at the Request package on NPM.
It's often good to abstract away your storage and dependent services to isolate changes and offer a consolidated and consistent web api for your application. But sometimes, if you have a good hypermedia web api (RESTful responses link to other resources), you could reference a resource link from another service in the response from your service (ex: SO request could reference gravatar image/resource of user). There's no one size fits all - it depends on whether you want to encapsulate the dependency or integrate with it.
It might be beneficial to make the web-api requests from your service exposed via expressjs as your own web-apis.
Making http web-api requests is easy from node. Here's another SO post covering that:
HTTP GET Request in Node.js Express
well, the way you describe it I think you may want to fetch data from amazon, lastfm and so on, process it with node, save it in your database and provide your own api.
you can use node's http.request() to fetch the data and build your own rest api with express.js

Resources