The journey to Single Page Application

I can understand that, I do feel we’re already on this curve, and the large payoff is coming.

We mixed so many libs and hacked them to work together over the past, right now, we are actually removing old functionalities and replacing them with implementations that used to coexists together.

I actually think we are very close to the end of the curve.

[import notes - user ‘gildub’ has not been recreated, so this post is currently assigned to ‘system’]

Hello,

Just joined - I work a lot around APIs, helping consuming OpenStack and through it helping ManageIQ (provider and related UI). I extensively used to deploy Satellite (5) and used The Foreman (Satellite 6) a bit (in the early days of OpenStack installer).

In the first place, discussions about GraphQL attracted my attention but there are also very interesting comments that similarly apply to ManageIQ, which is another big Rails app with similar UI evolution.

I think the crucial point is about strategy and how important that has been for both applications, which are benefiting from the flexibility of components “architectured” around the APIs. The Foreman architecture is impressive and quite advanced especially with the plugins.

So because API is so ubiquitous, I think GraphQL matters and must be a priority. Most here seem convinced of GraphQL benefits, not just as the next evolution step from REST, but with the potential to revolutionize API experiences and benefit everyone, from developers to consumers.

Regarding the SPA, my take is that nothing is going to replace AJAX with browser’s built-in language which also support event-driven paradigm, which in turn provides a solid base for more recent models such as reactive functional programming. What really matters isn’t a better support for specific paradigms? And by allowing to be more efficient, more adapted. In which case why not provide for the front-end developers needs?

Sure that’s a steep learning curve for the other developers (full stack) but once there it should be easier.

We have reached bottlenecks, stalling in re-factoring and debugging taking too long? So if more decoupling between UI components, data and state brings more efficient development, I take it.

And in the context of our long lived projects, as mentioned before, maintenance being primordial, it should help maintain the code.

I hope it helps.

Sorry I’m a little late to the party. I believe that the somewhat primitive angular SPA we have in katello has provided huge benefits to users. In production mode, once the application is loaded changing between pages is really quick and we are ensuring that our APIs work by using them extensively in our UI. The largest downside of the current katello angular SPA is that there is a lot of duplication of code mainly because we wrote this on an early version of angular before components were available. Obviously this makes it very painful to make changes in the application for developers.

Currently our new react application in katello is also a SPA for all pages within the set of pages. For example, everything in Red Hat Subscriptions links to other subscription pages in a SPA way using react-router but if you go to Red Hat Repositories from the subscriptions page you will get a full page load. I am hopeful that we can move to a full SPA in the future as we keep replacing troublesome pages and I think we’ll also make developer’s lives easier by creating a lot of reusable components along the way.

@ohadlevy one of the issues is:

replace turbolinks with SPA approach to load partial html content
http://projects.theforeman.org/issues/23449

What do you actually mean by that?
For a while, will be in a gap, where some routes can handle internally and some routes will still be going to need to receive HTML from a traditional controller.

As we discussed before, we can implement internal routing (probably react-router) but we will still need turbolinks/turbolinks-alternative to fetch HTML from the server when the page still hasn’t migrated to an SPA approach and still using the old server-side-rendering.

I took a long thinking on the subject, and read everything everyone here wrote.
I have a mixed feeling about it. Following a short discussion with Ohad, he encouraged me to write it here.

Some of what I’m writing here, already been raised, but trying to explain how I see things, so sorry from advance :slight_smile:

I’ved created a web based management tool for also technical stuff, that is fully SPA, and progressive loading, and I made a lot of errors in designing it properly, that it’s a pain to maintain, and today I’m not sure that it was right thing to do.

The reason is that the data store sometimes holds old information that hurts the current usage, and on every page mount, I found myself in the need to either reload things, or just validate information what i currently have. The thing is, is that foreman is much more complex then what I wrote vue.js in this case, and the system I’ved created have some very complex stuff in it.

On the other hand, what I’ved done so many times, is that each page act as SPA, that is 100% of what’s going on in that page is async javascript calls, and also web sockets, but each page is loaded and rendered by the server.

That worked for me much better, because it’s easier to create the proper API, and focus on functionality at the client side, and server side without limiting for a specific client side or server side technologies, so it was very easy to allow customers to integrate their own look and feel, while the server kept working, but it is not the case here. And I never created such system with integrated plugins.

The thing is, is that most current rails code becomes useless when moving to a real SPA, because even the routing will go over the client side, while the server side reports a 404 on a path request, the client capture it, and do the routing.

It means that the API calls must change, and then GraphQL comes in mind, and as mentioned, the API for tools such as hammer are a bit different then the UI, but the UI can use the same API, and also have additional API for it, for example user management, and other UI related stuff.

The thing that “scares” me here, is that the subject is so complex and requires so much trial and error before going to a path, and it’s not just “let’s go and see how it works”, because there are so many factors that will raise when testing, and I don’t think that there is right or wrong here, but only one big trail and error for trying to see what’s best suited for such system, after testing few paths and many types of usage and scenarios.

And when the best path for foreman will be found, I do see a lot of benefits for it.

Sorry for the scroll, but that’s how I see it :wink:

3 Likes

What exactly makes the development process much easier? How do you propose to actually achieve that? Because for me who has zero experience with modern JavaScript, it will be actually the opposite.

That’s weird statement, pardon me. In general, performance aspects must not “getting slowly worse”.

The “draw a triangle” article is wrong - you want to achieve as many as end to end tests (black box tests) as possible. Giving up from the start is the worst thing to do. Yes, it’s challenging. Yes, they can be slow. But if you have a good black box coverage, you actually don’t need unit tests at all! I am opinionated guy and I say (it’s not just me) - don’t write unit tests for everything. Testing a model CRUD is useless if you use it in a black box test. Only use unit tests during development, they should be also dropped from the codebase long term if they don’t break in months time-frame.

Speaking of responsibility, we can put test files anywhere we want, this won’t make anybody responsible. What’s much more important is component responsibility: every developer should own some components top to bottom. This makes them think about consequences - there are lots of things do consider. Deployment, configuration, installer, security, selinux, packaging, dependencies…

There is a simple solution for that, just save expiration timestamp together with your data and have a logic that makes the local data expired.
Kind of like you work with sessions.

Not necessary, the 404 is an hack you need to use when serving your assets from generic places like gh-pages or amazon-s3.
Those services won’t understand routes like https://example.com/page-1 because page-1 is not an asset, you will get 404 instead of the actual page.
To trick those services, you will modify the 404 results to make it render your actual app index/bundle.js so the app can load the and show the spesific route.
When you using a dedicated service to serve you SPA, you would handle it differently without render 404 error.

1 Like

Well put. Many modern technologies have the “hello world” problem. They work like a charm on small CRUD projects, but things start to screw up very quickly. Let’s be honest: Foreman is a beast. We are very large Rails project and we had to workaround dozens of things in 12 years old Rails codebase already. I am little bit worried here, that’s why I am actually against small evolution in favor of fully working prototype (including packaging, deployment, installation).

Software projects failure is high, this is no news in our domain. No matter how I’d love to see a single stack that’s fun to work with for everyone, if SPA fails I’d rather see a prototype failing rather than Foreman in production deployments. Every hour spent on reinventing wheel could be spent working on actual pains our users have. And we have lots of them: Issues - Foreman

3 Likes

It’s more complex then that, sometimes it’s good to have that information, and sometimes it’s a bug, and it’s not a trivial thing to know what and when, and what to do on each case.

As you and many others here knows (about the subject I’m writing in my comment), I have feeling need to explain that I just trying to explain my point of view, I know that you know this one already :slight_smile:

You have something called PATH_INFO. it’s a hack that dynamic scripting created, and web servers followed.
For example /index.php/a/b/c/d is a path info after the index.php (a very common in blogs for example).
Or even /host/1 that we are using in foreman is also a PATH_INFO.

When requesting a path from a web server, if there is a something for it to execute on that path, the server will give that something the ability to decide what to do, if the request is a static content, the server will return that content, and if the server does not understand what it is, there will be either 404 or other return codes based on what is wrong.

All of the client side routers are riding on a fact that the server will not do anything from the given path, and most of them are triggered on the 404 error, to understand that it’s their turn to do something.

The other way of doing it, is to ride on the fragment of the URL (that is the # char, aka anchor name in HTML). It is done on the client side, and never requested by the server, and it is handled by the “history” API, and URL object.

Please remember, you must have a server in order to do even the simplest bootstrapping, and most UI routers “ride” on the fact that the server will return something that they can capture and do.

Just my 5 cents on the matter :smile:

While I disagree about your view on unit tests usefulness and dropping policy, I definitely agree with responsibility. It’s not just sending code. To your list

Deployment, configuration, installer, security, selinux, packaging, dependencies…

I’d also add

  • adding API for the feature
  • hammer coverage
  • documentation

It’s slightly more nuanced than that. Unit tests quickly tell you if something broke with a strong indication of exactly where it went wrong. That can be useful. It doesn’t show you when a complicated interaction of various components breaks. end-to-end tests do. You need both. Dropping unit tests sounds like a bad idea because it makes refactoring much more uncertain. They provide guarantees about a units function.

That said, I fully agree that we need black box end-to-end tests. The whole stack is complicated and has many edge cases. It’s important (senior) developers understand what moving parts we have in the whole stack so they know what various changes affect.

2 Likes

Sure, dropping unit tests is an extreme I wanted to mention. I’d be very comfortable with having enough e2e tests, I don’t mind many unit tests.

Sorry to bring this to the attention, but there was a good discussion here but I don’t see many conclusions made. The RM issue tracker have few items associated but I just stumbled upon another thread Move “Hardware model” page to React and it looks like this is happening.

One of my concerns is that we move all the simple pages to React and then we can hit the wall called New/Edit host form. Is the most challenging form somewhere near top on the TODO list? If not, could we consider bumping it higher? Perhaps after 1.19 is branched, this could be THE feature for 2.0.

I think it’s okay to migrate two-three pages as a test, but then let’s focus of the challenges. The worst thing possible is that we migrate all of our app except New Host/Hostgroup. It can be a technical challenge, prioritization or lack of resources - it all happened before to other teams. We also want to avoid learning by doing, we want to do the challenging part first the hard way and then the rest should be piece of cake.

1 Like

Doesn’t it make more sense to have a new design for host pages besides blindly copying them?

the thought process behind moving simple pages (such as hardware models, or architectures) is to:

  1. have a complete page examples, folks have been asking for example to copy paste from, and as long as we just do small components (like the notification drawer, breadcrumb switcher etc) we limit future development to the current rails approach when creating new complete pages.
  2. we wanted to be able to start creating higher reusable elements so we can look into things like routing concepts etc, so that would mean we need to write at least a few simple pages (as it would speed up our ability to deliver in the mid term future).
2 Likes

I’d rather see us creating those components on paper and prototyping them separately and applying them onto New Host/Hostgroup first when they are ready to be used. My yesterday experience of current status of Repositories page in Katello which is undergoing new React design was not the best and I wonder if we will be rushing in patches after 1.19 freeze to fix UX issues.

This has something to do with my other concern: I am not comfortable with using Foreman as UX sandbox. This can be done separately, prototyping UX outside of target application is nothing uncommon. If this was some orchestration change, that would be challenging but this is I believe doable.

We already spent some time doing UX designs I believe, why not to take natural approach of prototyping them first, showing it to us where we can discuss these. Merge and fix later is not the best approach for UX IMHO. Let’s be careful, UX is something that everyone experience, comment and have feelings and opinions about.

2 Likes

I disagree foreman is a UX sandbox, in fact, most of the development of components is done on the patternfly-react (GitHub - patternfly/patternfly-react: A set of React components for the PatternFly project.) and you can see how the components are developed in isolation at https://rawgit.com/patternfly/patternfly-react/gh-pages/index.html.

When we are missing a component, e.g. for search auto completer, we developed the type ahead component, the same for other things like dual pane, notification drawer etc.

We are finally in a point it make sense to combine them in a single screen, to add more logic (above how it looks as behave as a unit) to how routing works, permissions etc.

I do agree with you that the subscription page was rushed, and took a few shortcuts, we should avoid that in the future.

We’re not doing it outside of the application, but there’s a “Labs” menu that you can enable in settings where the new pages are supposed to live during development. AFAIR the new repos page was there for some time and it was also demoed while still being on the labs page.

@Tomas_StrachotaI have seen an experimental flag in katello which seems pretty cool

Then why I have no idea? Can we please start doing some noise around this? When there is a new component, let’s start a thread on our community forums where we can discuss. Demos are simply not enough IMHO, this is pretty sensitive work, everyone is exposed to UI.

Frankly, I watched all demos in Foreman core history and I don’t remember much about incoming React components. I am pretty sure JS/UX/UI guys are doing tremendous amount of good work, the problem communication. There is an improvement already (Hardware model thread) but I’d like to see more on the PatternFly React level. It can be as simple as “here is new date picker, tell us what you think” and I am good.

When a page UI rewrite PR is filed, it deserves more attention than regular one and perhaps a separate thread on our site because our users don’t regularly do reviews on UI PRs but yet they want to be able to raise voice. I miss our “users” forum a bit which was turned into Support category, this should be probably more user-facing discussion.

There are few examples of components which I’d like to discuss:

  • the new breadcrumb with small menu (I don’t even know name for this)
  • notification drawer
  • possibly others (I have no idea what components were added because of Foreman)

It’s not that I have critical comments but rather to have an opportunity (and in right time not when things are done and merged and are in “yeah file a bug” state). Please don’t get me wrong, I am trying to end up with best possible UX for the future.

1 Like