<p>hi guys, started a course on golang that uses grpc and proto buffers to build a rest service. seems useful enough but the instructor doesn't really go into much detail as to the reason why he using these tools to build the api. any medium/blog articles out there on the pros and cons of grpc? thanks!</p>
<hr/>**评论:**<br/><br/>014a: <pre><p>I'm not sure about OpenAPI. I can describe my opinions on gRPC; maybe that will be useful.</p>
<p>gRPC has a lot going for it. Its nice that all CRUD operations are hidden behind simple function calls, and that the system has libraries in every major language to make this seamless. Its nice that validation is built in. I think the real seller is the easy streaming of input/output; most other approaches require you to build a pagination system on top of the technology they provide, usually you get best practices for doing this, but having it built-in and done for you is huge. Every single API will implement pagination at some point; I'm not sure why more libraries don't do it for you. The fact that it is implemented over the performant HTTP2 streaming protocol is a bonus.</p>
<p>There are a few things gRPC does I really really dislike, though.</p>
<ol>
<li><p>ProtocolBuffers. gRPC is designed to solve google-scale problems, but in doing so makes tradeoffs that organizations below Google scale (IE: literally everyone else) don't have to make. By operating over proto, you can't just <code>curl</code> endpoints to make requests (without additional work, there are libraries that proxy on top of grpc and do this for you), and your clients need access to the proto defs for the client libraries to work. This is nice because clients are guaranteed to access the same API the server is exporting, but it introduces tight coupling.</p></li>
<li><p>API is defined in a different language. I hate this, with a passion. We have all of this amazing tooling built-in to your server-side language of choice, especially Go, and then ptoto comes in and says "codegen this other thing into your language". It works, of course, or no one would use it. In interpreted languages this matters less, because the codegened protobufs are conceptually more like build artifacts. In Go and other compiled languages, you need them pre-build for both compilation (obviously) but also things like editor auto-complete and suppressing red squigglies. It would make more sense to design your API natively in Go, then have tooling during the build to export the protobuf files for consumption by clients. </p></li>
<li><p>Maturity. gRPC is notorious for having low code quality, especially in some of the tertiary languages. The documentation is also, in Google fashion, atrocious. Huge swaths are outdated. Some of it is flat-out incorrect. Nearly all of it is incomprehensible. All of their Getting Started guides just say "download this examples repo" which is a disgusting form of laziness. Fortunately, once you learn the basics its pretty easy to just pick it up and use it; just don't even try to learn the basics from Google.</p></li>
</ol></pre>ESBDB: <pre><p>how exactly is pagination built into grpc? streaming != pagination. If you want a paginated rpc call you will have to have OFFSET and LENGTH parameters in your request just like normal REST. </p>
<ol>
<li>You can't talk to any api without knowing the schema. I don't see how this creates tight coupling. This is no different to OpenAPI or even SOAP wsdl, except that it's a better implementation. Also gRPC != protobufs, it's merely the default serialization. You can plug in any serialization you want.</li>
</ol></pre>throwlikepollock: <pre><p>I think the pagination comment was in reverse. If you're needing streaming over plain http, one solution is a type of pagination. In fact, i'm implementing something soon that's in need of http streaming, so i'll likely be implementing it that way.</p>
<p>On that note, a bit of an aside, is there a better way that is both simple and works over plain HTTP? I just sort of defaulted <em>(mentally, no loc written)</em> to pagination. Is there something you like better?</p></pre>ESBDB: <pre><p>I still don't understand what streaming has to do with pagination. In the case of a defined set of data, pagination means random access to a subset of the data, where streaming means incremental access to the full set of data. In fact they're completely orthogonal as you can have both at the same time. You can request page 10 with a size of 200 and stream that subset to the client 1 or 10 at a time for example. Streaming in its raw form means the client starts reading and processing the data before the server is finished sending all the data. You can easily stream data over http by keeping the connection open and incrementally reading the data and processing it, just that json is a bad way to do this because it won't be valid json until all the data is sent. I assume there are js libraries that help with this, so instead of sending a single json object over a request, you send multiple, ie you don't put it in an array, then the client can parse 1 json object at a time and use that data before the next json object is finished sending. IMHO I would rather implement something over websocket, but that requires more overhead of dealing with websocket. You can also check grpc-web <a href="https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md" rel="nofollow">https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md</a> but I don't think it's ready yet last I checked.</p></pre>karlmutch: <pre><p>The following article might be helpful, I think the following article looks to be a good view of the state of things, <a href="https://medium.com/@timburks/openapi-and-grpc-side-by-side-b6afb08f75ed" rel="nofollow">https://medium.com/@timburks/openapi-and-grpc-side-by-side-b6afb08f75ed</a>.</p>
<p>Biggest con for us is the lack of pep8 for the python code generator. Makes it difficult to get the buyin of other teams when they are not pushing for the change.</p>
<p>The pro for me it's that gRPC and protobuf have more robustness and help on the human side by being very explicit.</p></pre>tex0: <pre><p>IMHO gRPC is an amazing approach, but the code is still rather incomplete and immature. We're using it in production, hit a few roadblocks and worked around them. Right now it works pretty good, but don't forget about the overhead. You should probably only use gRPC if you have a good reason to. Otherwise just stick with HTTP.</p></pre>tv64738: <pre><p>The Go gRPC library has a history of serious herp derp programming..</p>
<ul>
<li><a href="https://github.com/grpc/grpc-go/commit/3df1dd419a244c4a942c6a8b03ddc57e4fd4fec7">https://github.com/grpc/grpc-go/commit/3df1dd419a244c4a942c6a8b03ddc57e4fd4fec7</a></li>
<li><a href="https://github.com/grpc/grpc-go/commit/25dd388f9a5f61a32193fef98d28621c12c5f033">https://github.com/grpc/grpc-go/commit/25dd388f9a5f61a32193fef98d28621c12c5f033</a></li>
<li><a href="https://github.com/grpc/grpc-go/commit/b5774fd760d0ecea631fabc49eb3b94b3324df92">https://github.com/grpc/grpc-go/commit/b5774fd760d0ecea631fabc49eb3b94b3324df92</a></li>
</ul>
<p>There's plenty more there, that's just a quick sampling -- I stopped following the project more than a year ago. And then there's the bit where it reimplemented a http/2 server independently of net/http...</p></pre>Tacticus: <pre><blockquote>
<p>then there's the bit where it reimplemented a http/2 server independently of net/http</p>
</blockquote>
<p>Which was done so that they could provide http2 without tls on it. a feature not included in the net/http version.</p></pre>tv64738: <pre><blockquote>
<p>so that they could provide http2 without tls on it</p>
</blockquote>
<p><a href="https://godoc.org/golang.org/x/net/http2#Server.ServeConn" rel="nofollow">https://godoc.org/golang.org/x/net/http2#Server.ServeConn</a> ?</p></pre>chrj: <pre><p>Could you elaborate on the road blocks?</p></pre>BadlyCamouflagedKiwi: <pre><p>Why does pep8 matter? Why do you lint generated code files (a.k.a. build artifacts)?</p></pre>fasaxc: <pre><p>It's no the generated files, it's that ever call to one of the generated files looks ugly/uses different conventions. </p></pre>poofy_panda: <pre><p>I haven't used GRPC myself, but have found openapi useful. Particularly the codegen capabilities of swagger in openapi are nice. I can generate my server code fairly easily and then serve up the api desc to my js, who will parse that desc and dynamically create a client.</p>
<p>As the answer to your question, why use RPC in the first place? Large companies like Google and LinkedIn have many different processes each doing different specific jobs in what's called a microservice architecture. For example, LinkedIn might have a service whose only job is to keep track of connections and another service whose only job is collect the feed. Now imagine ~290 of these services, each with their own specific team. Now, each team could implement a rest api. But it is a hassle trying to convert native objects(say in Java) into a wire protocol like TCP or HTTP. You could use REST, but even then you would need to figure out how to encode it into a route and a payload. It would be a nightmare if every team implemented their own way of talking to each other. You as a service owner would need to maintain many different sets of clients to talk to each service. At LinkedIn scale, fanouts of a frontend service to backends can easily number around 20-30.<br/>
Now imagine a standard system that translates native objects and then makes requests with them to other services. This is RPC. You'll see various implementations like gRPC, SOAP, RestLI, openAPI, and GraphQL. </p></pre>ajgrf: <pre><p>Con: protocol buffers aren't self-describing. This is enough reason for me to look elsewhere unless I ever find myself desperately chasing better performance.</p></pre>twreid: <pre><p>Also load balancing becomes a problem too. For example ALBs in AWS do not load balance grpc services.</p></pre>65a: <pre><p><a href="https://grpc.io/blog/loadbalancing" rel="nofollow">https://grpc.io/blog/loadbalancing</a></p></pre>twreid: <pre><p>Yes there are solutions, but it's a pain and as I said in AWS the layer 7 ALB does not work with GRPC you are stuck with using a layer 4 load balancer or using a client side load balancer.</p></pre>ameoto: <pre><p>so use a better load balancer, envoy is pretty good.</p></pre>twreid: <pre><p>Cool I'll check it out thank you. Also this is mainly a con for me probably because the rest of our infrastructure is running on AWS no problem, but for this service that is using GRPC we are having to do a lot of extra leg work to get things like load balancing working compared to the other services.</p></pre>Kraigius: <pre><p>I'm going to answer with a big caveat here in which I only read about grpc and didn't build anything with it <strong>yet</strong>. I have a rest service which I'm going to attempt to port to grpc in the next week or so.</p>
<p>grpc is in early development. It's not that mature both in the sense of the spec itself and the grpc binding. C++ is first class as far as I can remember. Things like support for bidirectional streaming is meh.</p>
<p>The entire concept of cache control doesn't exist.</p>
<p>I did heard of people complaining about how errors are handled/raised and how confusing it can be. I'm not sure what this is all about.</p>
<p>Good on platforms that have a grpc binding but it can't directly be used on a web browser.</p>
<p>I remember reading about load balancing problems as sessions are sticky.</p>
<p>You can generate a rest service however, most of what you expect from an OpenAPI defined service isn't part of the protobuff spec. Things like providing examples, limiting parameters to certain set of values, defining responses, headers, etc. Either they are flat out missing or it's not that straight forward to do. When I was looking up to replace OpenAPI to protobuff I just straight up gave up on my goal to provide the exact same spec. It's a bit disappointing that I have to go 5 steps backward on my spec.</p>
<p>Protobuff is easier to write than yaml.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传