24 ms·
gRPC-Web: Moving past REST+JSON towards type-safe Web APIs
- Gigablah 9y agoThe title ("by Google and Improbable") is a bit misleading since it implies a collaboration between the two, when it's actually Improbable's own implementation that they released ahead of Google's pending spec.
- mwitkow 9y agoOne of the authors here. This is indeed our own implementation of the pending spec. We are in touch with the gRPC team to make sure that their (still unreleased) implementation is cross-tested with ours. The benefit of our implementaiton is a relatively light-weight client-side lib for Typescript and >=ES5, and a "ready-to-go" Go middleware.
- archgrove 9y agoEverything old is new again, except tunnelled over HTTP.
- breakingcups 9y agoYou mean like SOAP?
- sheeshkebab 9y agoLike CORBA, EJB, RMI, and a pile of other rpc libs and specs that died over the past 40 years.
- jlebrech 9y agowhy not emulate an RPC using webpack?
- progx 9y agoThere is a reason why more and more people left RPC and use REST. And for me "the next big thing" is something like GraphQL.
- mpweiher 9y agoBring back SunRPC and CORBA!
- grizzles 9y agoImo it was mainly poor language / framework support for asynchronicity. That's not really an issue anymore.
- pjmlp 9y agoSo how is the modern way to work around issues like network partitions, servers not responding, going off and on on network connections, duplicate answers,....?
- grizzles 9y agohttps://web.stanford.edu/~ouster/cgi-bin/papers/rifl.pdf https://web.stanford.edu/~ouster/cgi-bin/papers/rifl.pdf This paper says that exactly once execution of an RPC is possible. I have no idea if grpc does this or not.
- vertex-four 9y agoFutures-oriented programming - helped by the "async" or "generators" support in quite a few modern languages. Wrap timeouts and retries around everything, and process the timeout errors accordingly. RPC doesn't mean that a remote function call looks exactly like a local one. That was a mistake. Modern RPC systems return composable futures which make it trivial to do timeouts and retries, send off many requests at once and wait for all/some of them to return, and so on and so forth. If you're doing something that shouldn't happen more than once, generate a transaction ID to identify it by.
- andrewingram 9y ago
- andrewingram 9y agoI first saw this one a few weeks ago, and have been trying to weigh up its pros and cons over GraphQL (my tool of choice). gRPC-Web: * Speaks protocol buffers, a fast and compact format compared to JSON * Allows clients to use the same APIs as backend services. GraphQL: * Enables a client-centric view of the system. I have abstractions in my GraphQL server that only make sense to clients. It's a query-centric implementation of the Backend-for-frontend pattern, where the owners of the service are also the consumers. * Enables an entire UI's requirements to be fetched in one go (or optionally split up, if some content is less important). To achieve the same level of aggregation performance in gRPC would require building something analogous to GraphQL. The other benefits of gRPC-Web outlined in the article (generating typescript bindings) are equally possible with GraphQL (Relay Modern generates flow types, and is probably just one pull request from supporting TypeScript too) The status code standardisation only makes sense for single-purpose endpoints/calls, once you're dealing with aggregations, the semantics of a downstream status code will vary depending on the use case the query fulfills. I think both solutions have use cases, and can even happily co-exist. I don't believe gRPC-Web to be as much of a game-changer as GraphQL, but for certain scenarios (needing to rapidly fetch streams of data that don't have cross-dependencies) I can definitely see the benefits of a solution based on gRPC.
- al2o3cr 9y agoAllows clients to use the same APIs as backend services. Whether this counts as a bug or a feature depends on your APIs. I'm currently unfucking a suite of applications which bought into "your SPAs can just call backend services directly!" without getting a better security model - so the SPAs use hard-coded tokens that don't do any authorization, just like the backend services... facepalm
- andrewingram 9y agoPersonally I consider it a bug, but I was trying to avoid being too dogmatic in my comment, given it's clear i'm already decidedly biased in favour of GraphQL.
- euyyn 9y ago
- grw_ 9y agoThe reference implementation of gRPC on github[0] has 998 open issues and 215 open pull requests. Every time I've tried to use this package I have encountered a previously-reported issue which has remained unfixed for months. If you need to interact with Google platform it's hard to avoid using gRPC, since many "official" libraries seem to be migrating towards this library, while it remains fragile and bug-ridden. My "days since gRPC problem" counter is currently on "2", after hitting an issue which /crashed my python interpreter/ and required altering apache config to workaround[1]. [0] https://github.com/grpc/grpc/issues https://github.com/grpc/grpc/issues [1] https://github.com/grpc/grpc/issues/9223 https://github.com/grpc/grpc/issues/9223
- lyschoening 9y agoIt is worth pointing out that the Python implementation is particularly bad. Perhaps gRPC is really pleasant to use with Java and Go, but the Python implementation is neither usable nor stable enough for it to be worth considering its use for one's own services.
- JayOtter 9y agoMy instinct would be that it'll be just inherently nicer to use in a statically-typed language.
- lyschoening 9y agoPython can be statically typed.
- mwitkow 9y agoWe haven't tried using gRPC in Python, as we have completely migrated from Python away towards Go. Our experience of using gRPC in Java, C++ and Golang is pretty good. While it had some initial teething issues (when it was first released), the libraries have generally been a non-issue since the gRPC General Availability (GA-1.0 version). If you're considering using it in Go, check out the https://github.com/grpc-ecosystem/go-grpc-middleware https://github.com/grpc-ecosystem/go-grpc-middleware helper libraries that we've contributed back to gRPC Ecosystem.
- mvitorino 9y agoI think I like gRPC, but have several reservations regarding replacing REST with it. REST web services often return multiple mime formats, not just pure structured data. Some services return images, others return HTML, and then you also have cache... Maybe I just don't know enough about gRPC, but I can already imagine many people passing images around as byte arrays inside protocol buffers and when we look back, we have reinvented SOAP, which reinvented Corba.
- cshenton 9y agogRPC generates rpc server and client stubs based off a protocol buffer definition. Saying it's a replacement for REST makes little sense since it's possible to define a REST API within it. It's also possible to write a totally not RESTful API in a modern http api framework. In fact that's what Google's API design guide does. Encourages RESTful API design then describes how to implement them using proto and gRPC. The more interesting tradeoffs are proto vs json or other and how this restricts message patterns to request/response (rather than pub/sub or push/pull)
- mvitorino 9y agoInteresting! When I first looked at gRPC I missed the option(google.api.http). Are you aware of the reason why REST mapped gRPC is not possible in GAE (http 1 only on the server end of our code)?
- mwitkow 9y agoThere's actually a stand-alone proxy that translates the REST mappings of `google.api.http` into gRPC requests. It relies on code-generation: https://github.com/grpc-ecosystem/grpc-gateway https://github.com/grpc-ecosystem/grpc-gateway This has been the way we've been shipping our REST services until now, but the need to recompile the proxy was a major hinderence to our development speed. Hence gRPC-Web implementation.
- cshenton 9y agoProbably because it's pretty bleeding edge. Google Cloud Endpoints, which released earlier in the year, allows you to write a gRPC server, and offers the HTTP proxy as part of the service. The ecosystem still isn't quite there though. It could be easier to just write a thin webserver that just points at services over tcp (using something like ZeroMQ) rather than writing a service with gRPC from the ground up.
- grizzles 9y agoPersonally I'd prefer a promise based api. eg. stub.QueryBooks(qbr).then(...) A benefit of grpc coming to the web means someone will inevitably build a tool to parse a .proto file and generate a ui to test your microservices during dev. That will be cool.
- shaklee3 9y agoNot exactly a promise, but grpc has an asynchronous API.
- devoply 9y agoUnless I need high throughput, I am sticking with JSON Rest as it's good enough for most things and easier to debug by sticking a proxy in the middle or using ngrep.
- daliwali 9y agoRPC has its own set of limitations, which if your application qualifies, might be a good fit: * Coupled server and client. gRPC uses protocol buffers which have zero backwards compatibility. * Zero discoverability. The client knows in advance what the server can do. * No standards to follow. You make up your own specs, like Google did. These constraints are orthogonal to REST, the architectural principles behind the web. What they're doing is tunneling RPC over the web, which is what most HTTP APIs are doing already. There are only superficial differences like the use of protobuf, lack of verbs and URIs, etc.
- aristidb 9y ago"protocol buffers which have zero backwards compatibility" Either I misunderstand you, or this is _remarkably_ wrong: Protocol buffers were designed to make it easy to define protocols which are both backward and forward compatible.
- andrewingram 9y agoMy understanding is the same. Though I had also come to believe that the primary way to achieve this is via loose constraints, i.e. required fields should be used VERY sparingly. This compatibility pattern also leads me to conclude that protocol buffers aren't a suitable model for generating a client-side type system. You'll just end up with structures where everything is a Maybe type, so you end up needing tons of bespoke client-side code to handle the possible permutations. You need a layer on top of of them to express the true type system suitable for clients, and I believe GraphQL does a great job of this (but I hasten to add that even GraphQL's type system is relatively limited and isn't a magic bullet).
- vardump 9y agogRPC is based on protobuf3, which doesn't support "required" or "optional" in the first place.
- andrewingram 9y ago
- zargath 9y agoAnother hammer to a multifaceted problem, keep in mind that people have a lot of different use cases where JSON REST API's are the lesser evil. I only skipped through the spec for gRPC, but the protocol seems very limited. I dont like the 'gRPC status codes', where HTTP status codes at least can be grouped in ranges. The abstraction from the technology/protocol should not be the issue compared to the abstraction from the core business logic. When handling multiple consumers, customers and technologies I tend to worry more about where logic is handled and where data is stored, compared to how its transferred.
- jupp0r 9y agoThere is also Google's own implementation of this that has been in the works for some time. See https://github.com/grpc/grpc/issues/8682 https://github.com/grpc/grpc/issues/8682
- runeks 9y agoI don't understand this, to be honest. What does type safety have to do with serialization formats or application protocols? I've used Servant (Haskell) to define the REST API for my backend, which gives me type safety, server stubs and generated client code for free. In my view, type safety is about what you internally use to represent your API, and has nothing at all to do with the underlying protocol(s). There's nothing about REST+JSON that prevents type safety, as far as I'm aware. I plan to switch to protobuf3 for the serialization format, since this offers both a JSON and binary representation. Why would I want to choose gRPC+proto3 over REST+proto3?
- d--b 9y agoI think what they mean is by defining the contract first as a .proto file, and by having type-safe languages automatically read them and generate code, they are able to have a sort of cross language type safety. If you create a method like double GetThing(); and then you want to change it to: int GetThing(); All you have to do is change it in your proto, then both the typescript in the browser and the go code in the server will adapt, and shout at compile time if the types don't match. This wasn't the case when the server was sending JSON to a web listener. You'd have to hunt down the dependency to that method and change it.
- jayd16 9y agoBut unless you control all client code, you can't check the client code at server compile time. You're still breaking and forcing a refactor by all your clients and there's no way to track that with type safety. That said, this use case seems to be for a single web front end and go back end but that part is left out of the title. Protos are fine, google likes protos, gRPC works for Google because they have that insane CI system that builds every project at once...but any schema would work and you can be generating and checking against a schema for a JSON API as well. You don't need to move past REST and JSON to get what you're asking for.
- deleted 9y ago[deleted]
- IshKebab 9y agoThey sure do like spikes... whatever that means.
- neon_electro 9y ago"A spike is a product-testing method that is used to determine how much work will be required to solve or work around a software issue." [1] [1] https://en.wikipedia.org/wiki/Spike_(software_development) https://en.wikipedia.org/wiki/Spike_(software_development)
- IshKebab 9y agoAh, agile mumbo-jumbo.
- pg_is_a_butt 9y ago>Our Web App teams still needed to write JSON parsing code uh... your Web App teams took the day off and fed you shit. you're all idiots.
- lstroud 9y agoStub generation? Remote access protocols? CORBA all over again? So, now I know the next big thing. Portable distributed objects. :-P
- billsmithaustin 9y agoIt's wrong to assume that just because gRPC shares some design features with CORBA that it shares every CORBA feature or every CORBA shortcoming. There have been technologies to generate stubs, skeletons, and protocols from specification files for at least 30 years. Some of the older designs sprung out of a client/server world, whereas newer designs deal with today's reality, e.g. interoperability with today's web and the need for horizontal scalability. What hasn't changed is that it's still useful to describe a communication protocol in a declarative way and then rely on a code generator to provide the code to work with that protocol. Google protocol buffers offer advantages beyond that, but you may need to look beyond any preconceived CORBA biases to appreciate them.
- VMG 9y ago... on the Blockchain!
- lvh 9y agoCORBA tried to make remote calls look local. Making them look remote (and potentially even making some local calls look remote) is a very different design principle that leaks through almost every bit of the standard, and definitely leaks through to every bit of the implementation.
- oconnore 9y agoIt's funny to complain about CORBA's local/remote muddling in 2017 when we have moved on to microservices that also talk to each other locally with TCP/IP.
- camus2 9y agoOr AMF, everybody forgot about Flash and AMF?
- 9y ago
- beastman82 9y agoI'm using my own gRPC services and Google's speech recognition gRPC API and I absolutely love it. Protobuf/types, generated code, clear API contract.
- TimMeade 9y agoJust saw this during the morning reading. Without a deep dive, this looks very promising. We have recently been moving to k8s and grpc for our node work and the last piece was how to get to the browser. If this ties it all as one straight protocol from db to browser it will be very welcome and could not have come at a better time. We were evaluating the alternative (GraphQL etc) but our experiences with node and grpc have been excellent so far. Immediate evaluation planned.
- mwitkow 9y agoThat sounds very much what we're doing, except our microservice stack is in Go. For nodeJS you probably want to front your pods with grpcwebproxy (https://github.com/improbable-eng/grpc-web/tree/master/go/grpcwebproxy https://github.com/improbable-eng/grpc-web/tree/master/go/gr...) If you hit any snafus, please file bug reports in https://github.com/improbable-eng/grpc-web https://github.com/improbable-eng/grpc-web We're happy to help :)
- TimMeade 9y agoMuch thanks. I'll add it to the immediate list.
- linkmotif 9y agoThis kind of stuff couldn't happen soon enough. REST is so arbitrary and less than useful for building UIs. It's just bad. I've got Relay talking to a GraphQL service built in graphql-java which then talks to a gRPC service layer. The gRPC service layer is a great fit for GraphQL. Some type safety all around, but there could always be more. And there could always be less JSON. Please, no more JSON. The only thing it's good for is debug logging.
- grovesNL 9y agoI'm not sure why you need to modify your serialization or protocol to get type safety. I've been using NSwag (https://github.com/NSwag/NSwag https://github.com/NSwag/NSwag) to generate TypeScript clients from .ASP.NET controllers and it works great. It can generate TypeScript request/response handlers, and interfaces or classes for any public facing models.
- rdtsc 9y agoREST + JSON is simple, easy to debug, and it does the job. Web clients speak JSON, servers speak JSON, humans can read JSON usually. JSON can be gzipped so you get some benefit there. gRPC is another large pile of foreign C code that's essentially a black box. If there is a buffer overflow there that your code hits only somehow, you'd have to know how to debug it and fix it. Also chances are you are not Google, Facebook or Amazon , and you don't really do BigData just your know, regular data.
- ska 9y agoand it does the job. It does some jobs admirably. Because of the tooling and familiarity, it's often asked to do other jobs, and here the results are decidedly mixed.
- euyyn 9y ago> gRPC is another large pile of foreign C code that's essentially a black box Not for web, as this is generating Typescript code on top of the fetch API.
- yeukhon 9y agoBut I always thought speaking HTTP with a server can be considered RPC. We can pack our message in XML, JSON, or whatever serialization we choose, passes on to the destination, unmarshall, do something, return.
- godmodus 9y agoScalakka devops represent!
- j_s 9y agoDon't forget to protect against malicious user input! There are both pros/cons for 'non-human-readable' in the security department for sure. Finding a $5,000 Google Maps XSS by fiddling with Protobuf | https://news.ycombinator.com/item?id=13829925 https://news.ycombinator.com/item?id=13829925
- deno 9y agoYou can easily write an extension to in-browser Dev Tools to show human-friendly representation of any binary protocol for development/debugging purpose.
- j_s 9y agoNice. Are you aware of any Chrome extension for decoding Flash's 'application/x-amf' Action Message Format like Burp, Charles, and this Firefox extension do? https://addons.mozilla.org/en-US/firefox/addon/amf-explorer/ https://addons.mozilla.org/en-US/firefox/addon/amf-explorer/
- deno 9y agoNope, sorry! But Firefox addons will be soon switching to extension format compatible with Chrome, so you might get it for “free.”
- deleted 9y ago[deleted]
- deleted 9y ago[deleted]
- pspeter3 9y agoOne cautionary tale is to avoid generating code that exists at run time with Typescript. We managed to cause a severe page load regression for a while by generating Typescript for each DbObject and Projection (similar to a persistent GraphQL query). My advice is to only generate types and interfaces if possible.
- deleted 9y ago[deleted]
- didibus 9y agoI acknowledge it could just be me and the specific projects I worked on, but I've never been encumbered by an API style. RPC, Rest, GraphQL, I almost find them all to simply differ in syntax. I've managed to solve all my use cases using all three with equal effort, time and with comparable outcomes. There's value in compression and faster serialization/deserializarion formats when and only when micro-performance becomes an issue. Other then that, I think programmers spend way too much time debating over these, where I don't see any one of them providing an ROI advantage over the others.
- andrewingram 9y agoREST (in the pure sense) vs RPC is a valid comparison, but GraphQL solves a different problem. GraphQL is an alternative to other gateway API or backend-for-frontend solutions. The benefits of a gateway API to both developers AND users are hugely significant. These are decidedly NOT micro-optimisation.
- didibus 9y agoWhat's a gateway API? I acknowledge, I don't do a lot of frontend work. As I see it, GraphQL is just a query syntax that uses a JSON like language and where the query engine is built in code on the backend. You could replace all queries by REST requests, or build your own query language on top of JSON or RPC. In my experience though, anything approaching a query language was too expressive for an API, and it was better to offer one API per query, and encapsulate the queries on the backend themselves.
- andrewingram 9y agoGateway APIs: http://microservices.io/patterns/apigateway.html http://microservices.io/patterns/apigateway.html Assuming you've read that then I'd add the following. If you don't have something approaching a gateway, you're probably doing a big disservice to your users (assuming clients fetch data via API, rather than using a traditional render-on-the-server framework like Django or Rails). The value proposition of GraphQL is based on the assumption you're already doing things right by users, and its possible to fulfill the data requirements for a single page or app screen in a single API call. What this probably means is: * You have a custom endpoint per screen * That endpoint to either a) be versioned or b) support as many historical versions of your app as are in production * You might have a gateway per client (this is the full backend-for-frontend pattern) * Every time you add functionality, or change existing functionality, you're adding to what quickly becomes a huge set of endpoints What GraphQL promises (and delivers on) is the ability to get all the benefits of the backend-for-frontend pattern, without anyone ever having to write an endpoint specifically for a give client use case. The clients convert their data requirements into a query, and the GraphQL server returns the exact data you need, no more, no less. It requires some discipline when it comes to evolving the schema over time, but it works really really well. And when implemented intelligently has comparable performance to hand-crafted endpoints (I've written about how to approach this here: https://dev-blog.apollodata.com/optimizing-your-graphql-request-waterfalls-7c3f3360b051 https://dev-blog.apollodata.com/optimizing-your-graphql-requ...) When you experience the front-end workflow of using a library like Relay or Apollo (both are GraphQL clients) and having perfect synchronisation with UI and data, it's a really magical moment. You end up in a world where you can just get on with building UI, it's amazing.
- je42 9y agoIs this SOAP 2.0 ?
- westurner 9y agoWikipedia: https://en.wikipedia.org/wiki/GRPC https://en.wikipedia.org/wiki/GRPC Src: https://github.com/grpc https://github.com/grpc Docs: http://www.grpc.io/docs/ http://www.grpc.io/docs/
- beders 9y agoIt is still a bit shocking to see how many people are not getting the distinction between an API and a RESTful service. They are very different things and they have very different goals. The hint is in: how much do you value the client? If you have full control over both client/server or if we don't care about any 3rd party developing a client library for your service, then go with something like GraphQL or gRPC or SOAP with a nice, typed spec you can generate your code from and optimize the heck out of the bytes coming through the tubes. If OTOH you have an interest to create a RESTful service that is discoverable, that doesn't require constant client changes, that offer a wider variety of resource representations, that need to stand the test of time, then use HATEOAS and a RESTful architectural style. gRPC is yet another ... RPC. Nothing good or bad about that. Just make sure you understand the consequences.