Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

If you have client and server side and you have to check only in one place if conditions are met, this means that you cant check in client side anything and must do a server call, or implement both server side and client side in single codebase. Not sure if this is always feasible. Add DB to that and this means that you have to always check for constraints at DB level.


You could consider codegen from the single point of truth. Not always practical, but great when its set up with good ergonomics.


Codegen is great for lots of sync between client and server (I just wish there were more standardized tools), but what if it's a complex algorithm that you need to be able to perform both client and server side, assuming they use different languages?


You've answered one of the easiest ways to do it: just use the same language. Node (and Deno/Bun) is a good way to maximize code sharing and single points of truth.

But I definitely understand not everyone wants to write all of their backend in JS (or even TS). (Node ORMs sometimes don't have the polish of their cousins in other languages, for instance.)

There are great opportunities here for language mixing, however, in writing that complex algorithm in the same language for both frontend and backend but the rest of the codebases may not be in the same language.

1. V8/JavaScriptCore/SpiderMonkey are all very easy to rehost as "scripting languages" inside many languages people prefer to use on the backend. It's often easy to find wrappers to call JS scripts and marshal back out their results inside the backend language of your choice these days. You pay for transitions to/from JS to your primary backend language, of course, so it takes careful management to make sure these "business rules in JS scripts" aren't in any hotpaths, but a backend may have the cycles for that anyway.

2. WASM is offering more opportunities to bring some of your preferred backend language to the frontend. You probably don't want to write your whole frontend in WASM still today, as WASM still doesn't have the same DOM access, but using WASM for single point of truth business rules has gotten quite viable. You still pay for the startup costs and marshalling costs between JS and WASM, but in many cases that's all still less than network call. (I'm still skeptical of tools like Blazor for .NET, especially those building full frontends with it, but I definitely appreciate that reach of "write once" business logic for both client and server.)


You're assuming a web client. The example I had in mind was a mobile client, where we actually used a cross compiler to generate java byte code from swift to allow code sharing between iOS/Android clients, but that wasn't usable for the backends (which were C# mostly). Which is why I went with a server-precomputed lookup table in the cases the number of possible inputs made that feasible. If not, reg-exes for validation (with tooling to enable sharing between codebases) are a decent alternative in many cases. But I was curious what other options HN readers might have tried.


Option 1 applies to mobile frontends, too. In Swift you can always call JavaScriptCore to run a script. Android can use system-wide V8 or even bundle a smaller interpreter for JS.

(In fact, JS is the only "universal" scripting language in mobile due to Apple's fun restrictions that JavaScriptCore is the only JIT engine allowed on iOS. It really is the strongest option today for language to write things in if they absolutely need to be shared across all possible operating environments.)


That's where you need to consider practicality, and it degrades quickly. If it's fairly simple and compartmentalised code without external dependencies like services running on server, you could consider transpiling to target runtimes. But most likely at that stage you'll call a remote function through an API when you need that business logic on the client.


Sure, if performance isn't an issue (e.g. it might need to be done per keystroke). Small amounts of logic duplication like that can be annoying though, esp. when inevitably they end up not agreeing and users don't understand why they're being told their input is invalid. One option I've used is to have the server precompute all possible outputs for all possible inputs, it can work pretty well even with 10s of 1000s of entries.


One way to do this is to have a formal data schema as a separate artifact, which you then have as a dependency in your server and client projects, and generate the checks from the schema, as well as the SQL DDL.

But yes, if you have truly separate codebases it becomes more difficult, and protocols need to be quite stable and changes to them carefully managed.


> If you have client and server side and you have to check only in one place if conditions are met, this means that you cant check in client side anything and must do a server call, or implement both server side and client side in single codebase

Checks don't have to include the definition of knowledge independently, so multiple checks against the same rule don't need to be a violation. As a simple example, if you have a JSON Schema, that is the single source of truth for validation, and you can validate against it in 16 different places at different stages of processing and you haven't violated the principle that each piece of knowledge should be represented once in a system.


Have not thought about this. Good point. Constraints as a data not as a code. aka schema.


This is a huge advantage to using Node.js (or Deno) on the server. In a lot of my projects, I have a shared library that is used for data validation and constraints that is used on the frontend AND the backend. Makes validating data on both sides incredibly easy, and changing the library forces changes on the frontend and backend to match (enforced by automated tests)


> this means that you cant check in client side anything and must do a server call, or implement both server side and client side in single codebase

Or you derive one of the implementations from the other, or both from a third one.

But yeah, heterogeneous environments have a tendency of creating unnecessary code duplication.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: