SaaS News Hubb
Advertisement
  • Home
  • News
  • Software Engineering
  • Software Development
  • SAAS Applications
  • Contact Us
No Result
View All Result
  • Home
  • News
  • Software Engineering
  • Software Development
  • SAAS Applications
  • Contact Us
No Result
View All Result
SaaS News Hubb
Home Software Engineering

gRPC vs. REST: Getting Started With the Best API Protocol

by admin
June 7, 2022
in Software Engineering
0
SHARES
0
VIEWS
Share on FacebookShare on Twitter


In today’s technology landscape, most projects require the use of APIs. APIs bridge communication between services that may represent a single, complex system but may also reside on separate machines or use multiple, incompatible networks or languages.

Many standard technologies address the interservice communication needs of distributed systems, such as REST, SOAP, GraphQL, or gRPC. While REST is a favored approach, gRPC is a worthy contender, offering high performance, typed contracts, and excellent tooling.

REST Overview

Representational state transfer (REST) is a means of retrieving or manipulating a service’s data. A REST API is generally built on the HTTP protocol, using a URI to select a resource and an HTTP verb (e.g., GET, PUT, POST) to select the desired operation. Request and response bodies contain data that is specific to the operation, while their headers provide metadata. To illustrate, let’s look at a simplified example of retrieving a product via a REST API.

Here, we request a product resource with an ID of 11 and direct the API to respond in JSON format:

GET /products/11 HTTP/1.1
Accept: application/json

Given this request, our response (irrelevant headers omitted) may look like:

HTTP/1.1 200 OK
Content-Type: application/json

{ id: 11, name: "Purple Bowtie", sku: "purbow", price: { amount: 100, currencyCode: "USD"  }  }

While JSON may be human-readable, it is not optimal when used between services. The repetitive nature of referencing property names—even when compressed—can lead to bloated messages. Let’s look at an alternative to address this concern.

gRPC Overview

gRPC Remote Procedure Call (gRPC) is an open-source, contract-based, cross-platform communication protocol that simplifies and manages interservice communication by exposing a set of functions to external clients.

Built on top of HTTP/2, gRPC leverages features such as bidirectional streaming and built-in Transport Layer Security (TLS). gRPC enables more efficient communication through serialized binary payloads. It uses protocol buffers by default as its mechanism for structured data serialization, similar to REST’s use of JSON.

Unlike JSON, however, protocol buffers are more than a serialized format. They include three other major parts:

  • A contract definition language found in .proto files (We’ll follow proto3, the latest protocol buffer language specification.)
  • Generated accessor-function code
  • Language-specific runtime libraries

The remote functions that are available on a service (defined in a .proto file) are listed inside the service node in the protocol buffer file. As developers, we get to define these functions and their parameters using protocol buffers’ rich type system. This system supports various numeric and date types, lists, dictionaries, and nullables to define our input and output messages.

These service definitions need to be available to both the server and the client. Unfortunately, there is no default mechanism to share these definitions aside from providing direct access to the .proto file itself.

This example .proto file defines a function to return a product entry, given an ID:

syntax = "proto3";

package product;

service ProductCatalog {
    rpc GetProductDetails (ProductDetailsRequest) returns (ProductDetailsReply);
}

message ProductDetailsRequest {
    int32 id = 1;
}

message ProductDetailsReply {
    int32 id = 1;
    string name = 2;
    string sku = 3;
    Price price = 4;
}

message Price {
    float amount = 1;
    string currencyCode = 2;
}
Snippet 1: ProductCatalog Service Definition

The strict typing and field ordering of proto3 make message deserialization considerably less taxing than parsing JSON.

Comparing REST vs. gRPC

To recap, the most significant points when comparing REST vs. gRPC are:

  REST gRPC
Cross-platform Yes Yes
Message Format Custom but generally JSON or XML Protocol buffers
Message Payload Size Medium/Large Small
Processing Complexity Higher (text parsing) Lower (well-defined binary structure)
Browser Support Yes (native) Yes (via gRPC-Web)

Where less-strict contracts and frequent additions to the payload are expected, JSON and REST are great fits. When contracts tend to stay more static and speed is of the utmost importance, gRPC generally wins out. In most projects I have worked on, gRPC has proved to be lighter and more performant than REST.

gRPC Service Implementation

Let’s build a streamlined project to explore how simple it is to adopt gRPC.

Creating the API Project

To get started, we will create a .NET 6 project in Visual Studio 2022 Community Edition (VS). We will select the ASP.NET Core gRPC Service template and name both the project (we’ll use InventoryAPI) and our first solution within it (Inventory).

A

Now, let’s choose the .NET 6.0 (Long-term support) option for our framework:

An Additional information dialog within Visual Studio 2022. In this screen we selected

Defining Our Product Service

Now that we’ve created the project, VS displays a sample gRPC prototype definition service named Greeter. We will repurpose Greeter’s core files to suit our needs.

  • To create our contract, we will replace the contents of greet.proto with Snippet 1, renaming the file product.proto.
  • To create our service, we will replace the contents of the GreeterService.cs file with Snippet 2, renaming the file ProductCatalogService.cs.
using Grpc.Core;
using Product;

namespace InventoryAPI.Services
{
    public class ProductCatalogService : ProductCatalog.ProductCatalogBase
    {
        public override Task GetProductDetails(
            ProductDetailsRequest request, ServerCallContext context)
        {
            return Task.FromResult(new ProductDetailsReply
            {
                Id = request.Id,
                Name = "Purple Bowtie",
                Sku = "purbow",
                Price = new Price
                {
                    Amount = 100,
                    CurrencyCode = "USD"
                }
            });
        }
    }
}
Snippet 2: ProductCatalogService

The service now returns a hardcoded product. To make the service work, we need only change the service registration in Program.cs to reference the new service name. In our case, we will rename app.MapGrpcService(); to app.MapGrpcService(); to make our new API runnable.

Fair Warning: Not Your Standard Protocol Test

While we may be tempted to try it, we cannot test our gRPC service through a browser aimed at its endpoint. If we were to attempt this, we would receive an error message indicating that communication with gRPC endpoints must be made through a gRPC client.

Creating the Client

To test our service, let’s use VS’s basic Console App template and create a gRPC client to call the API. I named mine InventoryApp.

For expediency, let’s reference a relative file path by which we will share our contract. We will add the reference manually to the .csproj file. Then, we’ll update the path and set Client mode. Note: I recommend you become familiar with and have confidence in your local folder structure before using relative referencing.

Here are the .proto references, as they appear in both the service and client project files:

Service Project File
(Code to copy to client project file)
Client Project File
(After pasting and editing)
  
    
  
  
    
  

Now, to call our service, we’ll replace the contents of Program.cs. Our code will accomplish a number of objectives:

  1. Create a channel that represents the location of the service endpoint (the port may vary, so consult the launchsettings.json file for the actual value).
  2. Create the client object.
  3. Construct a simple request.
  4. Send the request.
using System.Text.Json;
using Grpc.Net.Client;
using Product;

var channel = GrpcChannel.ForAddress("https://localhost:7200");
var client = new ProductCatalog.ProductCatalogClient(channel);

var request = new ProductDetailsRequest
{
    Id = 1
};

var response = await client.GetProductDetailsAsync(request);

Console.WriteLine(JsonSerializer.Serialize(response, new JsonSerializerOptions
{
    WriteIndented = true
}));
Console.ReadKey();
Snippet 3: New Program.cs

Preparing for Launch

To test our code, in VS, we’ll right-click the solution and choose Set Startup Projects. In the Solution Property Pages dialog, we’ll:

  • Select the radio button beside Multiple startup projects, and in the Action drop-down menu, set both projects (InventoryAPI and InventoryApp) to Start.
  • Click OK.

Now we can start the solution by clicking Start in the VS toolbar (or by pressing the F5 key). Two new console windows will display: one to tell us the service is listening, the other to show us details of the retrieved product.

gRPC Contract Sharing

Now let’s use another method to connect the gRPC client to our service’s definition. The most client-accessible contract-sharing solution is to make our definitions available through a URL. Other options are either very brittle (file shared through a path) or require more effort (contract shared through a native package). Sharing through a URL (as SOAP and Swagger/OpenAPI do) is flexible and requires less code.

To get started, make the .proto file available as static content. We will update our code manually because the UI on the build action is set to “Protobuf Compiler.” This change directs the compiler to copy the .proto file so it may be served from a web address. If this setting were changed through the VS UI, the build would break. Our first step, then, is to add Snippet 4 to the InventoryAPI.csproj file:

  
    
      Always
    
  

  
    
  
Snippet 4: Code to Add to the InventoryAPI Service Project File

Next, we insert the code in Snippet 5 at the top of the ProductCatalogService.cs file to set up an endpoint to return our .proto file:

using System.Net.Mime;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
Snippet 5: Namespace Imports

And now, we add Snippet 6 just before app.Run(), also in the ProductCatalogService.cs file:

var provider = new FileExtensionContentTypeProvider();
provider.Mappings.Clear();
provider.Mappings[".proto"] = MediaTypeNames.Text.Plain;
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(Path.Combine(app.Environment.ContentRootPath, "Protos")),
    RequestPath = "/proto",
    ContentTypeProvider = provider
});

app.UseRouting();
Snippet 6: Code to Make .proto Files Accessible Through the API

With Snippets 4-6 added, the contents of the .proto file should be visible in the browser.

A New Test Client

Now we want to create a new console client that we will connect to our existing server with VS’s Dependency Wizard. The issue is that this wizard doesn’t talk HTTP/2. Therefore, we need to adjust our server to talk over HTTP/1 and start the server. With our server now making its .proto file available, we can build a new test client that hooks into our server via the gRPC wizard.

  1. To change our server to talk over HTTP/1, we’ll edit our appsettings.json JSON file:
    1. Adjust the Protocol field (found at the path Kestrel.EndpointDefaults.Protocols) to read Https.
    2. Save the file.
  2. For our new client to read this proto information, the server must be running. Originally, we started both the previous client and our server from VS’s Set Startup Projects dialog. Adjust the server solution to start only the server project, then start the solution. (Now that we have modified the HTTP version, our old client can no longer communicate with the server.)
  3. Next, create the new test client. Launch another instance of VS. We’ll repeat the steps as detailed in the Creating the API Project section, but this time, we’ll choose the Console App template. We’ll name our project and solution InventoryAppConnected.
  4. With the client chassis created, we’ll connect to our gRPC server. Expand the new project in the VS Solution Explorer.
    1. Right-click Dependencies and, in the context menu, select Manage Connected Services.
    2. On the Connected Services tab, click Add a service reference and choose gRPC.
    3. In the Add Service Reference dialog, choose the URL option and input the http version of the service address (remember to grab the randomly generated port number from launchsettings.json).
    4. Click Finish to add a service reference that can be easily maintained.

Feel free to check your work against the sample code for this example. Since, under the hood, VS has generated the same client we used in our first round of testing, we can reuse the contents of the Program.cs file from the previous service verbatim.

When we change a contract, we need to modify our client gRPC definition to match the updated .proto definition. To do so, we need only access VS’s Connected Services and refresh the relevant service entry. Now, our gRPC project is complete, and it’s easy to keep our service and client in sync.

Your Next Project Candidate: gRPC

Our gRPC implementation provides a firsthand glimpse into the benefits of using gRPC. REST and gRPC each have their own ideal use cases depending on contract type. However, when both options fit, I encourage you to try gRPC—it’ll put you ahead of the curve in the future of APIs.





Source link

Previous Post

Uber State Machine with Uday Kiran Medisetty

Next Post

On the quantum internet, data doesn’t stream; it teleports

Related Posts

Software Engineering

Write Better Commits, Build Better Projects

July 1, 2022
Software Engineering

The Overflow #132: The 2022 Dev Survey results!

July 1, 2022
Software Engineering

A Guide to Animating Mobile Data Visualizations

July 1, 2022
Software Engineering

Earthly Builds with Adam Gordon Bell

July 1, 2022
Software Engineering

Improve Git monorepo performance with a file system monitor

June 30, 2022
Software Engineering

Skilling up to architect: What you need to land high-paying IT roles

June 30, 2022

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Most Popular

News

How Customer Loyalty Can Drive B2B SaaS Business Growth

July 1, 2022
What is Gross Revenue? [+ How to Calculate & Record It]
News

What is Gross Revenue? [+ How to Calculate & Record It]

July 1, 2022
Software Engineering

Write Better Commits, Build Better Projects

July 1, 2022
Software Engineering

The Overflow #132: The 2022 Dev Survey results!

July 1, 2022
Software Engineering

A Guide to Animating Mobile Data Visualizations

July 1, 2022
Software Engineering

Earthly Builds with Adam Gordon Bell

July 1, 2022
Software Development

Pluralsight LIVE 2021 Week 1 recap: Stronger together

July 1, 2022
Software Development

Weekly News for Designers № 650

July 1, 2022
Software Development

What is Web 3.0 and Why it Matters for Your Business?

July 1, 2022

© 2022 Sass News Hubb All rights reserved.

Use of these names, logos, and brands does not imply endorsement unless specified. By using this site, you agree to the Privacy Policy

Navigate Site

  • Home
  • News
  • Software Engineering
  • Software Development
  • SAAS Applications
  • Contact Us

Newsletter Sign Up

No Result
View All Result
  • Home
  • News
  • Software Engineering
  • Software Development
  • SAAS Applications
  • Contact Us