28 ms·
Telefunc: Remote Functions instead of API
- seibelj 4y agoThis is pretty neat. You write a function and then a library automatically creates wrapper libs to be called in a browser as if it’s a function call. A variety of frameworks have done similar - SOAP auto-generated Java libs come to mind - but this looks very clean and minimal.
- Kalanos 4y agoi wish python worked like this w pickle
- contravariant 4y agoIf I recall correctly doing this with pickle does at least replicate most if not all of the security issues that java RMI has, so I guess it's most of the way there.
- seiferteric 4y agoI tried something years ago https://github.com/seiferteric/telepythy https://github.com/seiferteric/telepythy
- likeabbas 4y agoCall me a geezer but we had a name for this back in the day RPC - Remote Procedure Calls I’m not even 30 btw
- cton 4y agoIt’s still called RPC. https://telefunc.com/RPC-vs-GraphQL-REST https://telefunc.com/RPC-vs-GraphQL-REST
- likeabbas 4y agoI was making a joke
- avgcorrection 4y agoThe webpage calls it remote function. Close enough. Also the author: https://news.ycombinator.com/item?id=33054242 https://news.ycombinator.com/item?id=33054242 > Author of Telefunc here. I'm glad folks are finally taking RPC seriously.
- likeabbas 4y agoIt’s cute that JS/web devs are finally having a revelation about RPC, but it’s doing a disservice saying RPC hasn’t been taken seriously yet. Plenty of industries have been using RPC for decades
- chrsstrm 4y agoI guess everything old is new again. Welcome JS devs to RPC.
- belfalas 4y agoThere's not much new under the sun. Virtual machines were created in the 1960s, for example. The wisdom I was given by an old hand is that the computer industry goes through a cycle of focus: disk, network, CPU - at any given time the currently 'hot' technology is targeting one of these hot spots. I am not sure I have lived long enough to see this play out for myself but it seemed that there was some truth to it when I first heard it.
- ipdashc 4y ago> the computer industry goes through a cycle of focus: disk, network, CPU - at any given time the currently 'hot' technology is targeting one of these hot spots Which would you say we're in now?
- haimez 4y agoNetwork, and to a lesser extent: CPU (or more generally, compute) in large scale deployments as a result of possibilities enabled by networking. We’re calling this the cloud, but the first iteration of “the cloud” started with storage enabling efficient, reliable access of data storage being decoupled from individual nodes. Now we take that for granted- so maybe the current era is “all of the above, but storage started to feel like a solved problem”
- tharkun__ 4y agoWe’re calling this the cloud, but the first iteration of “the cloud” started with storage enabling efficient, reliable access of data storage being decoupled from individual nodes This is exactly what I dislike about all this "look, shiny, new" kind of thing. No, networked storage that is decoupled from compute nodes is not a cloud thing. Sure the cloud does that too. But data centers all over the globe used EMC^2 Symmetrix for a long time: https://en.wikipedia.org/wiki/EMC_Symmetrix https://en.wikipedia.org/wiki/EMC_Symmetrix
- 0xCAP 4y agoTrying to make me feel old by acting like you're too young to remember about RPC?
- brillout 4y agoThis isn't it (I do remember the SOAP days), the reasons I believe RPC is making a comeback: https://news.ycombinator.com/item?id=33054029 https://news.ycombinator.com/item?id=33054029
- leetrout 4y agoAre we also back to writing JS without semicolons?
- vyrotek 4y agoOur latest projects are built with RPC-style APIs and a BFF approach. We generate the TS client with Swagger and you effectively get strongly typed remote method calls. So basically, we're at SOAP again. A few more years and maybe we'll come back to Remoting?
- guggle 4y agoUsing JSON-RPC 1.0 here, with ad hoc client and documentation generation. So yes, basically SOAP-like, without the XML and "entreprise java" days cruft. Communication between frontend team and backend team is easy, everyone knows what a function is. No fiddling with ReST concepts for which everybody has its own personal interpretation. It's simple, it works.
- vyrotek 4y agoI've always been intrigued by JSON-RPC. How would you compare its benefits to something like Swagger? How do you like the extra verbosity of the message over the wire? Do you have a favorite generated TS client library?
- guggle 4y agoIt's really not about the tooling. I think you should go check this page: https://www.jsonrpc.org/specification_v1 https://www.jsonrpc.org/specification_v1 About verbosity, I'm not sure what you mean because it's has lightweight as any other JSON exchange. Of course there are other protocols based on binary messages, should you need that. But it's different.
- ianbutler 4y agoI think this is neat having looked at the examples but isn't the title really just a game of semantics? Non rigorously a web API is just the boundary across some service which you communicate with over (commonly) HTTP at the endpoints specified at that boundary by developers. I could write my own library that wraps those endpoints with functions that make the calls to them, in fact many libraries do just that. What this takes care of, again kind of nicely, is dynamically and automatically generating that boiler plate as you write your API so you don't have to put in the work, but I think saying this isn't just a style of building an API is a little much. Whether you're doing RPC, REST or whatever the boundary between your service and another service is it's API.
- jrumbut 4y agoRemote functions instead of data interchange doesn't have the same ring. Though I would say that RPC blurs a lot of lines. REST is clearly a way for two programs to communicate. RPC could be seen as a way for two programs to become one distributed program by means of location transparency. Shared objects and other systems take that a lot further, RPC is in a middle ground that is very interesting but also a little scary. Reading this description I couldn't tell you exactly what the security implications are. With their TODO list app as written, can a malicious user execute arbitrary SQL (within the permissions assigned to their user) on the server? It wasn't immediately clear to me (I'm sure a little more effort on my part could clear it up).
- brillout 4y agoSee my reply here https://news.ycombinator.com/item?id=33054110 https://news.ycombinator.com/item?id=33054110
- dboreham 4y agoWrong the first time. Still wrong.
- nixpulvis 4y agoWhy? The way people abuse HTTP JSON API design these days I figure it would just cut out a lot of the cruft. Maybe it's not the best way to do some things, but it might be a lot simpler... Well that is until someone writes a recursive function (or just a loop) which calls out to an RPC without consideration. But that's nothing new either.... How is `fetch(base + '/myFn')` all that different than just calling `rpc::myFn`?
- vyrotek 4y agoIndeed. So much code is an internal client function "GetUser(5)" configured to hit a specific URL "/users/5" and the server accepts requests on "/users/5" just to end up invoking a handler called "GetUser(5)". Definitely a fan of completely skipping the URL "REST" ceremony.
- icedchai 4y agoEventually you'll reinvent SOAP and be in for a world of pain and suffering with slightly incompatible or overly complex tooling.
- guggle 4y agoAnd here I am, enjoying JSON-RPC services since 2005, having none of the SOAP or ReST problems.
- quechimba 4y agoNice, I do something similar in a web framework I've been working on. All rendering happen on the server so the callbacks has to run there too. The onclick-handler in the DOM will trigger a POST to the server with an unique callback id. def self.get_initial_state(initial_count: 0, **) { count: initial_count } end def handle_decrement(_) update do |state| { count: [0, state[:count] - 1].max } end end def handle_increment(_) update do |state| { count: state[:count] + 1 } end end def render <div class={styles.counter}> <button on-click={handler(:handle_decrement)} disabled={state[:count].zero?}> - </button> <span>{state[:count]}</span> <button on-click={handler(:handle_increment)}> + </button> </div> end
- 77pt77 4y agoGreat! SOAP, RPC and CORBA. Here we go again.
- unnouinceput 4y agoFuck CORBA. Please, don't even joke about it.
- 77pt77 4y agoDistributed loops now in javascript. Maybe you can also pass closures around...
- vyrotek 4y agoBring out your dead... SOAP, Remoting, COBRA. :) https://twitter.com/MontyPythonOps/status/1292183567959638016 https://twitter.com/MontyPythonOps/status/129218356795963801...
- hsn915 4y agoThat's exactly how I program my APIs. The urls even look like '/rpc/FuncName' The backend language I work with is Go, so there are "two" problems that need to be solved for this to work: - Resolving function name and encoding/decoding arguments from a url to a real function call - Representing Go structs as Typescript interfaces for the client side code to look like regular function calls with regular types and all that. For the second part, I have a writeup about how I'm doing it: https://hasen.surge.sh/go-ts-type-bridge.html https://hasen.surge.sh/go-ts-type-bridge.html It's worth noting that the title of the OP website is wrong. "Remote Functions Instad of API" What do you think an API is? API does not stand for "HTTP Requests with JSON". It stands for "Application Programming Interface".
- deleted 4y ago[deleted]
- brillout 4y agoYea, I've seen a lot of folks doing this and it's neat. Most projects don't really need REST/GraphQL. So many waste so much time implementing a perfect GraphQL setup even though they don't need it :sweat_smile:. I don't think "API" just means "programmatic interface". It also denotes some kind of decoupling. A library API => decoupling between lib user and lib author. GraphQL API => decoupling between backend and frontend. The point of Telefunc is precisely to not decouple frontend and backend. Telefunc is all about bringing backend and frontend tightly together. So, the tagline is very much on point ;-). But, yea, you make me think that "Remote Functions. Instead of REST/GraphQL." is maybe better. I'll think about it.
- asim 4y agoIt really is a game of semantics as another person commenting mentioned. It might feel like there's something distinct here but all RPC was remote procedure calls aka functions and produced tightly coupled clients and server code. And the term API is not specifically owned by HTTP calls or REST/GraphQL, it's a definition of an interface for consumer some service. Even in your case whether you feel like you see it or not, every function is part of an API.
- Cushman 4y agoCool! Y’all, this is obviously an RPC interface, but the point is that `import { onNewTodo } from './CreateTodo.telefunc.js'` is not, as written, an RPC. That transform, with seamless type support et cetera, is what makes this interesting. (If you think it’s interesting.) I think it’s interesting; I experimented with a higher-magic version of this a couple of years ago. (It had continuations to support returning callbacks, could preserve object identity, and could lift inline anonymous functions to the server with some amount of intelligence.) My goal was to make the RPCs as close as possible to local async functions, which was really fun when it was working. My experience was that for the simplest use cases, the ergonomics were unbeatable. Just drop a `@remote` tag into your TodoMVC frontend, and there’s your TodoMVC backend. But as soon as I had to look under the hood (for something as simple as caching behavior), the “just a function” interface was a distraction and I found myself wishing for a more conventional RPC interface. (I think that might be why you tend to see this sort of magic more in the context of a full framework (such as Meteor), where all the typical use cases can be answered robustly. If you’re building your thing out of modules, cleverer abstractions usually mean more work overall to integrate everything and boring is better.)
- ekidd 4y agoJoel Spolsky had an ancient article titled "Three Wrong Ideas From Computer Science" (2000): https://www.joelonsoftware.com/2000/08/22/three-wrong-ideas-from-computer-science/ https://www.joelonsoftware.com/2000/08/22/three-wrong-ideas-... Some parts of this don't hold up that well. But it has a section titled "Network Transparency" that talks about when transparency of fails. And he calls out three things that make network calls fundamentally different: 1. Availability. It's possible that your network "function" will be impossible to call for some amount of time. 2. Latency. The round-trip latency of RPC calls is extremely high, which affects API design in major ways. Typically, you wind up wanting to perform multiple queries or multiple operations per round-trip. 3. Reliability. Network calls may fail in many more ways than local calls. And these are all issues that have defeated many "transparent" RPC systems in the past. Once your application spreads across multiple machines that interact, then you need to accept you're building a distributed system. And "REST versus RPC" is relatively unimportant compared to the other issues you'll face.
- edfletcher_t137 4y ago"Rock-solid The source code of Telefunc has no known bug" No known bugs does not "rock-solid" make. This claim alone makes this project very hard to take seriously.
- brillout 4y agoI'm also the author https://vite-plugin-ssr.com/ https://vite-plugin-ssr.com/, which I'd argue is rock-solid as testified by the companies sponsoring it.
- andkenneth 4y agoYeah man, I would kill for the endorsement of myfavouritequiltstore.com, they're my favorite quilt store.
- dharmaturtle 4y agoHow does this compare to https://trpc.io/ https://trpc.io/ ? Edit: so far, I'm preferring trpc, because it has support for zod and a few other libraries https://trpc.io/docs/v9/router https://trpc.io/docs/v9/router It seems like this library has its own bespoke syntax for types https://telefunc.com/typescript https://telefunc.com/typescript
- neonedge 4y agotrpc relies still on strings: No proper refactoring (ie F2 in VS Code) which makes refactoring as slow and error-prone as with REST and GraphQL. Should change with v10 but its API hasn't been finalized yet and ETA is far in 2023 if at all. Also overall API design has missed opportunities. Telefunc should support zod, why shouldn't it? Just pass them as native zod types and all good. You could also convert them before with z.infer but you don't need to. > It seems like this library has its own bespoke syntax for types Only for stacks which don't transpile server-side code. You can use normal TS types with something like Next, Nuxt, Svelte, Vite, etc. So, these bespoke types aren't relevant for the majority.
- cehrlich 4y agov10 is in beta and will go into RC fairly soon. I'd put my money on a 2022 final release. I'm already using it in production and it's rock solid. Only complaint is still having to restart the TS server in your editor occasionally due to all the inference magic it does.
- brillout 4y ago> Telefunc should support zod, why shouldn't it? What's your use case for wanting zod instead of https://telefunc.com/shield#all-types https://telefunc.com/shield#all-types?
- panzerklein 4y agoZod has a lot of features. And an ecosystem.
- 4y ago
- spullara 4y agoWe should revisit this before RMI https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing https://en.wikipedia.org/wiki/Fallacies_of_distributed_compu...
- hexo 4y agoDon't wanna break it for you - but calling even a remote function exactly is "using an API" (application programming interface). I like the logo (or icon) they have, that masquerades it as some serious haskell (or some other functional PL) related project. If it was this easy eveyone would be using RPC all over the place for many years already, and we'd have no HTTP and no train-load of other protocols.
- akiselev 4y ago> If it was this easy eveyone would be using RPC all over the place for many years already, and we'd have no HTTP and no train-load of other protocols. People are using RPC over HTTP all the time. Most backend APIs I've seen are only vaguely RESTful [1] and everyone seems to stuff much of their critical functionality in JSON RPC APIs masquerading as POST endpoints. [1] no true scotsman and HATEOAS ¯\_(ツ)_/¯
- brillout 4y agoThe reason RPC is making a comeback is because of 1. SSR (e.g. rendering React components to HTML on the server-side), and 2. the increased practice of continuous deployment. Increasingly, the frontend is deployed hand-in-hand with the backend. RPC is a match made in heaven for stacks where backend and frontend are deployed in-sync. There really are only two reasons for using a RESTful/GraphQL API: providing third parties access to your data (e.g. Facebook API) or decoupling frontend and backend (e.g. Netflix uses a loosely coupled microservice architecture). Most projects don't need either.
- revskill 4y agoIt's like React 18 server component :D
- _sohan 4y agoThis reminds me of the ScriptMethod thing that asp.net has in the early days of AJAX. Was fun to use it, but didn’t stand the test of time. https://learn.microsoft.com/en-us/aspnet/web-forms/overview/older-versions-getting-started/aspnet-ajax/understanding-asp-net-ajax-web-services?source=recommendations https://learn.microsoft.com/en-us/aspnet/web-forms/overview/... Maybe there has been enough changes in the ecosystem now to be able to abstract network and write code that’s not too brittle.
- deleted 4y ago[deleted]
- brillout 4y agoI actually have plans to make Telefunc also have sensible defaults for network failure. So that the user doesn't have to take care of that (while the user can customize failure handling if he needs to).
- recroad 4y agoHaving lived through EJB 2.x, this is a hard pass. I don’t want to pretend the sever is local when it’s not.
- stingraycharles 4y agoAnd if it has to be not, I much rather have an Erlang / OTP-like approach where resilience and failure recovery is so fundamentally baked into the language, it’s an actual feature instead of a liability.
- diceduckmonk 4y agoReally odd how there is a dozen comments on RPC but no one mentioned gRPC for the web browser. Google goes in the reverse, where from both protobuf you autogenerate API boilerplate, client stubs and even REST-over-HTTP apis. https://github.com/grpc/grpc-web https://github.com/grpc/grpc-web
- brillout 4y agogRPC is nice for backend-side RPC, but the ergonomics of Telefunc are much nicer if all you need is your frontend to access data.
- tbrownaw 4y agoThe first rule of network transparency is : the network is not transparent.
- brillout 4y agoYes, and that's why in Telefunc's world remote functions are called "telefunctions" to differentiate them from normal functions.
- zemnmez 4y agoif you can query the DB directly from the frontend, what’s the security model? what prevents me from pulling sensitive data, passwords etc?
- andkenneth 4y agoIt doesn't, you still write frontend and backend separately, it just deals with the stuff in the middle for you.
- andkenneth 4y agoI'd much sooner recommend tRPC, which is much more mature and doesn't make bogus and weird claims on its website.
- brillout 4y ago> doesn't make bogus and weird claims on its website Feel free to elaborate. I'm also the author of https://vite-plugin-ssr.com/ https://vite-plugin-ssr.com/ which indeed has no known bugs.
- tanelpoder 4y agoSo now we’ll have another layer of an RPC API that under the hood calls the already existing REST API?
- danbruc 4y agoWhat exactly is the difference between an API and a remote function?
- brillout 4y agoImagine a To-Do app, and you want to implement a new feature "mark all tasks as completed". With a RESTful API you do these requests: GET https://api.todo.com/task?completed=false POST https://api.todo.com/task/42 { "completed": true } POST https://api.todo.com/task/1337 { "completed": true } POST https://api.todo.com/task/7 { "completed": true } With RPC/Telefunc, this is what you do instead: export async function onMarkAllAsCompleted() { await sql('UPDATE tasks SET completed = true WHERE completed = false') } The crux the matter is that a RESTFull/GraphQL API is a set of generic endpoints that are set-in-stone and that are designed to be able to serve all kinds of frontends, whereas with RPC you implement endpoints as-you-go that are tailored to your frontend. For example, if you want to provide third-parties access to your data, then RPC wouldn't make sense. You need an API for that. On the other hand, if all you need is your frontend to access your database, then an API really is just an unnecessary indirection. (Although for large teams an API can be useful to decouple the frontend from the backend.)
- madsbuch 4y agoThere is not reason why your couldn't expose an endpoint that lets you marked completed a filtered query. You can implement arbitrary DSLs over REST / GraphQL. Philosofically, there is no difference though each have their own connotations. You expect RPCs to be much more integrated in a language and an API to run over standard transport protocols using standard data formats. However, this is isomorph.
- wruza 4y agoWith RPC/Telefunc, this is what you do instead: get_tasks({completed:false}) add_task({id, …}) update_task({id, completed}) upsert_task({id, …}) delete_task(id) Or a meaningful subset of it, also set in stone when appropriate. There is no reason to start being unreasonable with your APIs once you switch underlying protocols. And no protocol will stop you from doing POST /sqls <some sql> Also, pedantically, your POSTs are wrong. You have to PUT (or likely PATCH in this case) into /task/:id, or POST into /tasks. https://restfulapi.net/rest-put-vs-post/ https://restfulapi.net/rest-put-vs-post/
- ochronus 4y agoRPC is cool again! CORBA FTW ;)
- maskaler 4y agoSOAP for browser is finally here.
- brillout 4y agoWithout all that XML crap :grinning:
- vinay_ys 4y agoGoogle has a system called plaque in which you can express DAGs of operators (functions) and it handles all the scheduling and data flow between nodes running on a distributed cluster. This achieves much better performance efficiency at large distributed scale while also providing an easy to reason and debug program logic. I would expect more such distributed computer programming models with dedicated language/compiler toolchains in the future.
- brillout 4y agoI think we will eventually see this: if you want to give third parties access to your data then use GraphQL. For any other use case use RPC. I.e. public access => GraphQL, internal access => RPC.
- kamilafsar 4y agoWhoa, that’s so similar to our project [1] it’s almost scary :) How are errors handled though? What happens when you “throw Abort()”. https://github.com/samen-io/samen https://github.com/samen-io/samen
- brillout 4y agoThe frontend-side also throws an error. `throw Abort()` is about protecting telefunctions from third parties. It shouldn't be used to implement business logic (simply use `return` instead). Samen => Neat :-).
- jasperpressplay 4y agoSamen can throw errors on the server that can be caught on the client. Is that possible with telefunctions?
- asim 4y agoThe thing about people with experience, we love to tell you about the past. The cycles are all the same, technology A is created, it has some level of success, then something else (B) is adopted. A new generation of developers have only experienced B and due to its shortcomings reinvent A as C. And the cycle repeats over and over.
- brillout 4y agoThis isn't it (I do remember the SOAP days), the reasons I believe RPC is making a comeback: https://news.ycombinator.com/item?id=33054029 https://news.ycombinator.com/item?id=33054029
- brillout 4y agoAuthor of Telefunc here. I'm glad folks are finally taking RPC seriously. RPC is back. Smarter, leaner, and stronger. (Sorry for the marketing jargon, but I really do believe that.) Telefunc is still fairly young, you can expect a lot of polishing in the coming weeks/months. The high-level design is solid and I expect no breaking change on that end. If you encounter any bug (or DX paper cut), please create a GitHub Issue and I'll fix it. I'm also the author of https://vite-plugin-ssr.com https://vite-plugin-ssr.com which also has no known bug, so I do take that claim seriously. Let me know if you have any questions!
- majestic5762 4y agoThe DX is really cool, but I remembered protobuf exists https://buf.build/blog/connect-web-protobuf-grpc-in-the-browser https://buf.build/blog/connect-web-protobuf-grpc-in-the-brow... The marketing rhetoric of telefunc activates my skepticism, but I hope it's just me
- brillout 4y ago> The marketing rhetoric of telefunc activates my skepticism Why? (Author of Telefunc here.)
- crummy 4y agoWe have a hand-rolled solution that does this and it's easily my favourite part of our codebase. Ours is with a Java backend so a bit more complicated but not much. If you have a tightly coupled frontend and backend and no need for third party consumers of your API, I highly recommend it. Makes moving between frontend and backend such a pleasant experience with a well typed and defined interface.
- tobr 4y agoCould this be used to communicate between the main thread and a worker too?
- brillout 4y agoIt's quite a different use case with different constraints. It's out of Telefunc's scope.
- tobr 4y agoThat’s understandable! Are there specific constraints you are thinking of? I did a simple implementation of RPC for workers a few years ago, but it would be really nice to get the import transforms Telefunc handles for you.
- bluelightning2k 4y agoThis seems like a very nicely done implementation. One negative: I don't think people realize how easy it will be to inadvertently include server side files in client side bundles. The technical approach mitigates this and is well designed. But simply by blurring the lines it might result in sever side config bundled to the client. (Easy to mitigate, just add a line to server side stuff which and destructs if it detects wrong environment)
- rilut 4y agoI love this, so convenient. Any plans for python server?