Do we need a web API?
liaison.dev
liaison.dev
When I started doing web development in the late 90s for about ~5 years I was the designer, front-end, and backend developer all in one. Then over time things changed to allow for specializations and we now have many different functions, and that's a good thing. RPC has a place, and it's not for web apps, at least most of the time.
I've noticed over the years that JavaScript developers tend to try and put their JavaScript everywhere and I often wonder if it's because they don't want to learn other technologies. Don't get me wrong, I like a little bit of JS too - I even added JavaScript support to an old 2D Game engine using SpiderMonkey (before V8 was a thing) back in the day so that I could make desktop games with JavaScript. I just don't want to do _everything_ with JavaScript. Especially with so many interesting languages and technologies to play with these days.
Are JavaScript developers today the PHP guys of the past?
Where I work, having one language has made things simpler when doing tasks. Don't need to look things up as much because you keep forgetting which one uses push vs append, etc.
Oh, you're a poet, right? I need you to write some legal documents. You are already expert in English, so it should be easy.
Personally I have never understood backend JS as you get untyped, weird silent errors, under or completely un-utilized async features that end up causing more problems than they solve, and then all the quirks of JS to boot. I regularly hear the argument of the benefits of keeping the language the same on both ends, but besides slightly easier JSON between them (something handled by clean packages in almost every language these days with minimal effort/LOC/boilerplate) the languages don't end up actually sharing a ton given how you hook into a web framework like Express, database API's, etc. You don't get code reusability and I don't think the JS tradeoffs are worth the slight savings on context switching. If you have a serious project of any scale/long term use and have front end programmers that want to use JS on the backend, either bite the bullet and have them learn now or hire some backend devs in a language better suited to your project.
I usually take a front-end first aproach, but there are also lots of people taking a backend first aproache where they rely more on static analysis, compilation, unit tests and packaging - rather then manually testing every LOC.
And automated regression tests before pushing are in ever other language as well.
> the love for instant feedback
What languages can you not get this with?
> And I also use automatic regression tests before pushing to prod.
That's 100% language agnostic...
> Node.js is infamously known to use small modules, it however gives you battle tested code run by thousand in production
Many other languages have extensive packages pulled in, but that says nothing about how battle tested the code is unless all of the packages have high use. Python has plenty of packages with the same use level. Java has tons as well. The list goes on.
You shouldn't try to pull a fast one on HN readers, it won't work most of the time.
But the communication protocol (https://deepr.io) in between is language agnostic. So it is possible to imagine Liaison being ported to different languages in the future.
gRPC can already do that but gRPC's design is unnecessary bloated. The nice thing about RPC is its potential of zero-config setup. gRPC totally fails on that and it's painful to setup gRPC.
The RoR/python server could be used to automatically serve the RPC API. For a zero-config setup.
It always baffled me how so-called RESTful APIs became popular, despite virtually all of them being RPC APIs with a veneer of rather pointless HTTP semantics.
Virtually none of those APIs do anything to serve the intentions and goals behind REST[1]. Furthermore, many RESTful APIs end up being wrapped into language-specific clients anyway, because they have poor ergonomics in their raw state.
I consider RESTful APIs the most significant anti-pattern not widely recognized as such.
[1] https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arc...
That said, for an API consumed by third-party developers, REST makes a lot of sense. Otherwise, which is like 98% of the APIs out there, RPC really is superior.
I've implemented a tool similar to what OP is building: Wildcard API [1]
> rather pointless HTTP semantics.
Agree. Actually, while implementing Wildcard API, I made sure to abstract away all HTTP semantics. With Wildcard, you don't think in terms of "HTTP verbs" but you think in terms of functions. Like you are naturally used to.
> It always baffled me how so-called RESTful APIs became popular
I believe REST became popular because it got lot's of exposure since all third-party APIs were using REST.
Simplicity? Have you ever tried to integrate distributed applications that do not share the same codebase?
And calling REST anti-pattern tells me that you aren't that familiar with alternatives.
>despite virtually all of them being RPC APIs with a veneer of rather pointless HTTP semantics.
If you want to do RPC over HTTP and pretend that it is REST interface, it isn't really a problem of REST.
The only feasible logical end to this is ASP, which was an interesting idea when it was launched 19 years ago
Regarding the number of XHR calls, to be accurate, it is not 6 but 4. Once Liaison is complete and optimized, the number of calls should drop to 2.
Also, please keep in mind that Liaison is made for building single-page applications. So, using it for a simple blog might not be the right choice.
And about your security concern, please head over here: https://news.ycombinator.com/item?id=21660785
The problem of serialization, deserialization, versioning, endpoint design... They aren't an artifact, they're intrinsic to how Web apps are built.
But yeah, for small projects I think this could be really neat.
Add: my PTSD from a few months with DCOM is acting up :)
Except they actually implement things like validation, because as much as one may want to unify both environments, the reality is that exposing all your methods to the outside world may have some pitfalls, to put it mildly.
Plus, React came out and blew Meteor out of the water.
Diagram from this project: https://github.com/liaisonjs/liaison/blob/master/assets/cros...
Diagram from CORBA: https://en.m.wikipedia.org/wiki/File:Orb.svg
Don't hide the communication layer pls.
They write the Javascript for you but you won't even notice it.
I don't have experience with Phoenix, but with Blazor I just write my complete SPA in C#. There is no API for communication between the server and client. Blazor creates all the JavaScript websocket code for me so I never need to write a single line of Javascript.
And when you separate your business layer from Blazor you can always add an API in the future when you need one. Just create some controllers for your API and use the same business code Blazor is using.
--Martin Fowler
About authorization, Liaison doesn't expose anything by default. Only the specified attributes and methods are exposed, and there is an authorization mechanism so you can customize what you want depending on the user.
What frustrates me is that it's not the API that is the source of complexity. ~80% of the pain of building most apps comes from managing the syncronization of state between the client and server. SPAs are the over-prescribed opiates here making the problem worse. Imagine what could be possible if you walked away from maintaining client state altogether.
We did, and it's wonderful. StimulusReflex let me build a reactive tabular UI with sorting, filtering and pagination with 115 LOC, none of which is custom JS: http://expo.stimulusreflex.com/demos/tabular
I honestly believe that the existence of things like StimulusReflex and LiveView demand we question the ongoing utility of libraries like React. Popularity is not a good reason to use something, especially when you realize you could be radically more productive if you don't use it.
One of the big things is that the benefit declines over time. The amount of code reuse you get is sub-linear with respect to the size of the project. As the project matures, GUI code and back end code diverges. That leaves you stuck in a framework that ends up not necessarily optimal for server side, and not necessarily optimal for client side, and the amount of code you end up writing to coordinate between them ends up outweighing the actual business logic.
The things that are successful tend to focus on problems that increase with greater than linear complexity as your app matures. Spend time focusing on these instead. Don't lock yourself into a framework that prohibits it.
This. This is why ASP.NET, ServerFaces, JSP+Taglibs, etc. became a nightmare.
If you worry about cluttering the business logic and want to clearly separate the exposed API, you can expose subclasses of your domain models instead.
Liaison and tools like it essentially create a monolith exactly where something is screaming to be two separate services. You want to be able to deploy versions of server side and client side code independently. You want to be able to ensure you don't break clients that have web pages open when you deploy the new server version. You want clients to be able to run where JS isn't available.
About interoperability with non-JS environments, I wrote an article about that: https://liaison.dev/blog/articles/How-about-interoperability...
If your goal is just a brain workout then by all means keep going with it. But if you're looking to do something that gets some larger adoption, then I'd probably wrap this up and move on to the next thing.
(Not that you asked my advice, or that I'm in any way qualified to give it)
https://docs.microsoft.com/en-us/dotnet/api/system.web.scrip...
Monoliths are a big problem and merging frontend and backend into each other only made it worse...
How does this work? Do you need some cross-network locking mechanism when you need to make sure the shared object's state doesn't get out of sync between client and server?
What about passing object instances between client and server? Does it do what (I think) DCOM does to handle garbage-collection of cross-machine object references – keep-alives and timeouts?
a) scale, and
b) adapt over time
you're going to find yourself decoupling and slapping APIs on both ends to adapt to the transport mechanism.
So for a boutique app, you might get away with a client-server model.
Its just about is it the right tool for the job.
I don't like their comment : 'They are just a necessary evil so the frontend can communicate with the backend'
If your backend only communcates with an SPA and nothing else, then yup, this is a good tool for that job.
If i'd do a SPA that has 'node' backend, i'd just use typescript to model the API and you can have shared models and compile-time type safety.
Because the separation is more or less obligated if people wanted to do interactive web pages, instead of people want to separate them as different services for different problem domains.
People who don't like write JavaScript can stay tuned, as WASM age comes, there would be a burst of things like this but not in JavaScript (eg: Blazor).
I'm the author. I'm glad to see that RPC is getting more and more traction.
- and thank God gRPC never took off the way Google hoped, it was pure ego and politics like the majority of OSS projects these days (in the web world)
Does this handle "API" versioning in any real way?
For a flat blog post? Like, seriously?
cooming soon: web assemply web 3.0 which (I fear) might feel a lot like flash web pages from the early 00s. I hope I'm wrong.
I don't know want to call what we have now.
There are some benefits, of course. Stable and standardized UI is finally available as a baseline for devs (much like early Windows/iOS software) and all roads are clearly leading toward a unified design model for phone apps/web/desktop. Bloat and needless complexity are the biggest issues at the moment, but all the frameworks seem to be (finally) focusing on becoming more snappy.
also, most offensive is the use of 3rd party js hosting. given the tiny size of the 3rd party libraries (relative to 1st party code), add them in to the code from your own site (which you're already bundling up. SMH)
[from jsdelivr.net]
polyfill.min.js (31.8kb/96.8kb) (wire/resource)
url-polyfill.min.js (1.9kb/6.1kb)
react.production.min.js (4.7kb/12.3kb)
react-dom.production.min.js (36kb/116kb)
[from liaison.dev]
bundle.a7c7d78d57.immutable.js (108kb/375kb)
actual website code: https://github.com/liaisonjs/liaison/tree/master/website
About the fact that I have used Liaison to build its own website, I agree that it might not be the best choice. :)
For now, Liaison doesn't support server-side rendering, but it is something that could come eventually.