Live data from Hacker News

tRPC – Build and consume typesafe APIs without schemas or code generation

trpc.io

171–180 of 223 posts

Re: tRPC – Build and consume typesafe APIs without schemas or code generation

#171

Earlier quoted context omitted.

TypeScript is actually a great schema language and fixes a number of problems in GraphQL's SDL, especially the lack of generics. I think if you're defining a JSON API, that TypeScript is a natural fit since its types line up with with JSON - ie, number is the same in both and if you want something special like an integer with more precision, then you have to model it the same way in your JSON as your TypeScript inter…

Jesus, if you're making a JSON API just use JSONSchema, which while not perfect, is quite nice for language interop (and more powerful than typescript)

> just use JSONSchema

I'll "just" use the type system built into my programming language until the pain of supporting multiple languages is more expensive than installing JSONSchema tooling and messing with code generation.

Re: tRPC – Build and consume typesafe APIs without schemas or code generation

#172

Earlier quoted context omitted.

This is the overlooked advantage of a schema (e.g. in GraphQL): it forces you to think about the data types and contract, and serves as a good way to align people working on different parts of the code. It also scales to other languages besides TypeScript which helps if you ever want to migrate your backend to something else or have clients in other languages (e.g. native mobile apps in Swift, Kotlin, etc).

TypeScript is actually a great schema language and fixes a number of problems in GraphQL's SDL, especially the lack of generics. I think if you're defining a JSON API, that TypeScript is a natural fit since its types line up with with JSON - ie, number is the same in both and if you want something special like an integer with more precision, then you have to model it the same way in your JSON as your TypeScript inter…

TS is a pain with JSON Schema or OpenAPI because it doesn't directly support things like integer or precision. TS does not easily support things like `"exclusiveMinimum": 5`, `"type": "integer"` or patterned (regex) fields.

So if you want to convert your TS interfaces to JSON Schema, you may need to provide additional constraints via JSDoc and use a generator that understands those annotations. But your TS interfaces cannot express those constraints directly.

There are a number other related complications surrounding these more expressive schema definitions - like building types from them and interacting with them at runtime.

Re: tRPC – Build and consume typesafe APIs without schemas or code generation

#173
post #87

I'm currently in the process of removing tRPC from our codebase. It's been a nightmare of tight coupling. I've also found that it encourages more junior developers to not think about interfaces / data access patterns (there's a mapping from Prisma straight through to the component). It's fantastic for rapid prototyping but really paints you into a corner if you ever want to decouple the codebase.

It's a dangerous anti-pattern to pass your db types through to your api handlers. Those are always different models and it's important to have an intermediary representation for the rest of your domain.

Re: tRPC – Build and consume typesafe APIs without schemas or code generation

#174
post #21
post #7

We’ve use an API style similar to tRPC at Notion, although our API predated tRPC by 4 years or so. You can build this kind of thing yourself easily using Typescript’s mapped types, by building an object type where the keys are your API names, and the values are { request, response } types. Structure your “server” bits to define each API handler as a function taking APIs[“addUser”][“request”] and returning Promise . T…

In our current project with a TS frontend and Python backend, we use an OpenAPI schema as the source of truth and openapi-typescript-codegen [0] to interface with it on the client side. While not perfect, it provides a very nice interface to our API with request/response typings. I also wrote a 10-line mock API wrapper that you can call as mockApi ((request) => response), and it will type-check that your mock functio…

Another great library to generate TS types from OpenAPI is https://github.com/drwpow/openapi-typescript . It provides the types as single objects you access via indexing, which is pretty nice. There's a partner library to generate a typed fetch client.

Re: tRPC – Build and consume typesafe APIs without schemas or code generation

#175

Dropping in a tRPC use case that I've really got a lot of mileage out of: communication between the Electron main and renderer processes using https://github.com/jsonnull/electron-trpc . Traditional Electron IPC is hard to do type safely, which electron-trpc solves, and the react-query integration (meaning you get automatic type-safe hooks to issue the requests) is really nice.

Hey there, author of electron-trpc here. I'm always happy to hear that folks get value out of the integration and have a good time using it. Thanks for the mention!

Re: tRPC – Build and consume typesafe APIs without schemas or code generation

#176

I love tRPC, it's by far the best fullstack DX I've ever seen and has such a brilliant API especially when combined with Zod. Zod and tRPC are some of the most important projects in the future of TS imho, I think we're gonna see a beautiful bloom of tRPC inspired DX across the TS space in coming years. Two projects already have clearly have tRPC DNA attacking different use cases are Ping's UploadThing ( https://githu…

I just checked out the Zod intro pages but I still don’t know what problem it’s trying to solve. What is it adding to TypeScript (which I am not conversant in either)?

Thanks for any insight!

Re: tRPC – Build and consume typesafe APIs without schemas or code generation

#177
post #151

Earlier quoted context omitted.

What's the point of the middle layer? Seems like an extra step and a language change for no reason. Why not just expose HTTP from your Rust stuff?

Because you lose all the stuff that’s nice about tRPC. The experience of building a tRPC app is very different from building an app that talks to a traditional REST API. The front and back end with tRPC are very tightly bound. In a way the backend part of your tRPC app becomes the real consumer of your actual API.

Okay. I see 3 main benefits of the tRPC experience.

1. You don't need to manually write HTTP routes on the server side.

2. You don't need to manually write request code on the client side.

3. There's a type contract between both.

I don't see how this "thin server" approach helps with any of these.

1. You're no longer writing HTTP routes, but instead you're writing gRPC. You haven't eliminated the work, you've just changed the technology. If you happen to be integrating with a pre-existing gRPC deployment, why re-invent the wheel with custom TS code instead of using one of the many gRPC->HTTP transcoders?

2. Modern web frameworks have so many abstractions on this pattern that it's a non-issue at this point.

3. Your thin server is effectively a mapper from gRPC to HTTP endpoints. That's the type of thing you can build a spec from. If you've used a transcoder and have a spec, you can codegen your client library with the correct types.

I think tRPC works best for making highly cohesive full stack apps. Using it as a middleman for your backend seems weird to me.

Re: tRPC – Build and consume typesafe APIs without schemas or code generation

#178
post #87

I'm currently in the process of removing tRPC from our codebase. It's been a nightmare of tight coupling. I've also found that it encourages more junior developers to not think about interfaces / data access patterns (there's a mapping from Prisma straight through to the component). It's fantastic for rapid prototyping but really paints you into a corner if you ever want to decouple the codebase.

It's a dangerous anti-pattern to pass your db types through to your api handlers. Those are always different models and it's important to have an intermediary representation for the rest of your domain.

Agreed. Although, sometimes it feels like this is a losing battle. I've worked with too many people who see that level of separation as "unneeded duplication", with constant complaints about having to update a bunch of different layers "just to add a new field.

IMO, at a minimum, you have your API layer model, your internal model, and your database model with a mapping layer at each boundary.

I rarely have problems when I structure it that way, but when working on applications that pass the same model from their API down to their database, or vice-versa, it's always full of the same types of problems that comes with tight coupling.

Re: tRPC – Build and consume typesafe APIs without schemas or code generation

#179

Earlier quoted context omitted.

TypeScript is actually a great schema language and fixes a number of problems in GraphQL's SDL, especially the lack of generics. I think if you're defining a JSON API, that TypeScript is a natural fit since its types line up with with JSON - ie, number is the same in both and if you want something special like an integer with more precision, then you have to model it the same way in your JSON as your TypeScript inter…

TS is a pain with JSON Schema or OpenAPI because it doesn't directly support things like integer or precision. TS does not easily support things like `"exclusiveMinimum": 5`, `"type": "integer"` or patterned (regex) fields. So if you want to convert your TS interfaces to JSON Schema, you may need to provide additional constraints via JSDoc and use a generator that understands those annotations. But your TS interfaces…

You can easily express constraints like these with Zod though (created by the same person who created tRPC v1)

Re: tRPC – Build and consume typesafe APIs without schemas or code generation

#180

Earlier quoted context omitted.

For what it’s worth I have never heard of RSC and it’s not googleable. Have a link?

React Server Components. Sorry, I edited the comment above.

Believe it or not, not everyone is even using a flavour of React.

One nice side effect of using tRPC is that you can pack up and move to a different framework on the front-end if desired, and a lot of the tRPC work can be used directly

Post reply on HN