2
15 Comments

Do we need a fully typed Server-Client Protocol?

I have this idea, and a prototype in the works, that allows our team to write code (once only) for the "bridge" between any client and server, that can work over http (request - response type), sockets (event based) or even RTC (for a p2p architecture), and that comes fully typed on both ends.

The end result is almost like an SDK that abstracts the whole networking details (url routes, http methods, communication protocols (http, socket, etc.), outside of the business logic both on client and server. Probably a fully typed RPC framework is even more like it.

It currently only works in typescript (browser and node), and all the checks happen at runtime so there's no need to write definitions or schemas, just regular code that lives in a separate library/repository and imported at build time. In the future it could be expanded to other languages as well.

This is an example:

server code

import { AsyncErr, AsyncOk } from 'ts-async-results';
import { init } from './pipeline/server';

const pipeline = init({
  // TODO: The port should actually come from the 
  // pipeline codebase so it's bundled together with
  // the client on the same version
  port: 8080,
})

pipeline.user.onRequest('single', async (request) => {
 // handle the onRequest and return an 
 // AsyncOk or Async Err, to get sent over the wire. 
 // This is the analog of res.send(data) in express
  
 cost myUser = await db.getUser({id: request.id});

 if (myUser) {
   // Look into https://github.com/movesthatmatter/ts-async-results 
   // for more info on the ts-async-result
   return new AsyncOk(myUser)
 }

  return new AsyncErr({
    type: 'InexistentResource',
    content: request.id,
  })
})

client code

import { init } from './pipeline/client'

const pipeline = init({
  httpUrl: 'https://localhost',
  wssUrl: 'https://localhost'
})

pipeline.user.request('single', { id: '2' })
   .map((user) => {
     // success code
      console.log('user', user);
   })
   .mapErr((e) => { 
       // fully typed errors

       if (e.type === 'InexistentResource') {
           // handle 
       }

       // handle otherwise
   })

Does this sound appealing to anybody? If so please leave a comment or feedback below and I'll be more than happy to give more details.

Do we need a fully typed Server-Client Protocol?
  1. Yes
  2. No
  3. Maybe if it's done right
Vote
posted to Icon for group Developers
Developers
on April 18, 2022
  1. 1

    I mean I use asp.net core so model binding is there so you know you screwed up at compile time... There's extensions libs that goes the next steps to just automatically sync data and stuff...

    Or you are thinking something like Refit: https://github.com/reactiveui/refit Refit: The automatic type-safe REST library for .NET Core, Xamarin and .NET

  2. 1

    publish it on hackernoon

  3. 1

    Sounds like GraphQL

    1. 1

      Hey @fromtheexchange, react server components are an awesome concept I believe, but they are tied to react only and although I see similarities I believe what I'm proposing is at a level lower than the components.

      1. 1

        I mean, the concept is cool and it reminds me of https://github.com/GoogleChromeLabs/comlink a bit, but honestly react server components will probably solve all my problems in a couple years.

        1. 1

          Comlinks are interesting – never heard of them before but yeah, that could in theory be solved too.

          Oh yeah, as long as it solves all you need it makes a lot of sense. It's also baked by the react team so it's a no brainer. For me I just like to work in these type of ideas, and instead of just building it I decided to ask for some feedback first, hopefully other people could be interested and are willing to add their input.

          Thank you!

  4. 1

    I don't know if I fully understood it, but does it add additional bytes (for types) in network communication?

    1. 1

      Hey @Mayursinh, no it doesn't! The types are only used at compile time. It's literally typescript code that gets shared between the client and the server.

      I can show you more details if you want and even a working example in a few days or so

      1. 1

        Ook, Then I think its good. Most people always advocates for having types. If this solution is not much boilerplate-like overhead then people might gradually adopt.

        Assume I have an API endpoint, /get/foo with defined response types in server. Now from client if I write fetch('/get/foo'), how would I know types of the response with the solution you presented?

        1. 1

          So, the trick is to not think in terms of routes anymore, as all of that is abstracted away, but in plain old function calls. In other words instead of calling fetch(“/get/foo”) you call resources.foo(), just like any other function.

          This automatically returns an Async Result , which can be Ok or Err.

          1. 1

            Would resources have all the server defined routes as a function with types?

            1. 1

              Yep. It would be structured something like this

              • Resources.User.getAll()

              • Resources.User.getOne(id: string)

              • Resources.User.create(user: User)
                etc…

              • Resources.Posts.create(post: Post)

              • Resources.Posts.get(id:string)
                etc…

              1. 1

                I just came across this while exploring cal.com code on Github. https://trpc.io/

                1. 1

                  Yesss! That's pretty much what my idea is. TRpc definitely looks pretty robust, and I'm glad someone does it well. It might have a few differences in my vision and theirs but very awesome still.

                  Also a bit sad someone else already did it haha!

Trending on Indie Hackers
I'm a lawyer who launched an AI contract tool on Product Hunt today — here's what building it as a non-technical founder actually felt like User Avatar 150 comments A simple way to keep AI automations from making bad decisions User Avatar 54 comments “This contract looked normal - but could cost millions” User Avatar 54 comments Never hire an SEO Agency for your Saas Startup User Avatar 42 comments 👉 The most expensive contract mistakes don’t feel risky User Avatar 41 comments The indie maker's dilemma: 2 months in, 700 downloads, and I'm stuck User Avatar 40 comments