Skip to content

Creating a gRPC API with multiple proto files

This guide will walk you through deploying a GRPC API that has multiple .proto files for its API definition. For this, we will use the Order Service API. You can download the zip file containing the various proto files from the link given below.

Order API: OrderDefinition.zip

Sample Backend for Order Service API

We will use the sample Order Service backend for this guide, which can be created using the following command. Let's create it in the same namespace we deployed the APK in.

kubectl apply -f https://raw.githubusercontent.com/wso2/apk/main/developer/tryout/samples/order-sample-backend.yaml -n <namespace>

You can check the status of the pods by using

kubectl get pods -n <namespace>

Creating and deploying the API

The following steps are a quickstart guide on deploying a GRPC API that has multiple .proto file as its API definition.

Step 1 - Obtain the proto files for the given API

Download and save the following files.

Order API: OrderDefinition.zip

Step 2 - Generate the APK configuration

Execute the following request to generate the APK configuration. Use the values provided in the table below in the body of your request.

Field Value
definition The zip file that was downloaded at the beginning of Step 1.
curl -k --location 'https://api.am.wso2.com:9095/api/configurator/1.2.0/apis/generate-configuration' \
--header 'Host: api.am.wso2.com' \
--form 'apiType="GRPC"' \
--form 'definition=@"/Users/user/OrderDefinition.zip"'
curl --location 'https://<host>:9095/api/configurator/1.2.0/apis/generate-configuration' \
--header 'Host: <host>' \
--form 'apiType="GRPC"' \
--form 'definition=@"<path/to/zip-file-containing-proto-definitions.zip>"'
name: "32398767b3b64a7ba1c6aabcd042df4fbd42502a"
basePath: "/grpcapi"
version: "v1"
type: "GRPC"
defaultVersion: false
subscriptionValidation: false
operations:
- target: "order.OrderService"
  verb: "CreateOrder"
  secured: true
  scopes: []
- target: "order.OrderService"
  verb: "ServeOrder"
  secured: true
  scopes: []
- target: "payment.PaymentService"
  verb: "ProcessPayment"
  secured: true
  scopes: []
- target: "user.UserService"
  verb: "GetUser"
  secured: true
  scopes: []

You will get the apk-conf file content as the response, as seen in the above sample response. Save this content into a file with the .apk-conf file extension. You will need to fill in the name and endpoint configuration fields before deploying the API.

Note

  • The .proto file has the package string, which is used to get the basepath and version of the API.
  • The structure of the package string should be package <basepath>.<version>.<package-name>
  • The basepath and version are autogenerated from the contents of the proto file. If you modify it in the API, ensure that you also modify it in the .proto file prior to generating any code from it.
  • For an API that has multiple proto files for its definition, each proto file must have the same basepath and version in each proto file. The service name can vary.
  • For example, in the Order Service API,
    • Package names: order, payment and user
    • Basepath: /grpcapi
    • Version: v1.
    • Therefore, the package string in the proto files should be grpcapi.v1.<package_name>. Here, it is grpcapi.v1.order, grpcapiv1.payment and grpcapi.v1.user.

Step 3 - Updating the APK-Conf file

Let's add the endpoint configurations section to the file as follows.

endpointConfigurations:
    production:
        endpoint: "http://order-backend:6566"

The URL "http://order-backend:6566" points to the backend we deployed in the previous section.

Let's also rename the API from the autogenerated string to "OrderServiceAPI".

Your apk-conf file will now be as follows.

    name: "OrderServiceAPI"
    basePath: "/grpcapi"
    version: "v1"
    type: "GRPC"
    defaultVersion: false
    subscriptionValidation: false
    endpointConfigurations:
        production:
            endpoint: "http://order-backend:6566"
    operations:
    - target: "order.OrderService"
      verb: "CreateOrder"
      secured: true
      scopes: []
    - target: "order.OrderService"
      verb: "ServeOrder"
      secured: true
      scopes: []
    - target: "payment.PaymentService"
      verb: "ProcessPayment"
      secured: true
      scopes: []
    - target: "user.UserService"
      verb: "GetUser"
      secured: true
      scopes: []

Step 4 - Deploy the API

To deploy the API, we need a valid access token issued by an identity provider (IdP). Follow the Generate Access Token documentation to generate an access token.

After generating the token, you can deploy the gRPC API with the following command.

curl -k --location 'https://api.am.wso2.com:9095/api/deployer/1.2.0/apis/deploy' \
--header 'Host: api.am.wso2.com' \
--header 'Authorization: bearer eyJhbGciOiJSUzI1NiIsICJ0eXAiOiJKV1QiLCAia2lkIjoiZ2F0ZXdheV9jZXJ0aWZpY2F0ZV9hbGlhcyJ9.eyJpc3MiOiJodHRwczovL2lkcC5hbS53c28yLmNvbS90b2tlbiIsICJzdWIiOiI0NWYxYzVjOC1hOTJlLTExZWQtYWZhMS0wMjQyYWMxMjAwMDIiLCAiZXhwIjoxNjg4MTMxNDQ0LCAibmJmIjoxNjg4MTI3ODQ0LCAiaWF0IjoxNjg4MTI3ODQ0LCAianRpIjoiMDFlZTE3NDEtMDA0Ni0xOGE2LWFhMjEtYmQwYTk4ZjYzNzkwIiwgImNsaWVudElkIjoiNDVmMWM1YzgtYTkyZS0xMWVkLWFmYTEtMDI0MmFjMTIwMDAyIiwgInNjb3BlIjoiZGVmYXVsdCJ9.RfKQq2fUZKZFAyjimvsPD3cOzaVWazabmq7b1iKYacqIdNjkvO9CQmu7qdtrVNDmdZ_gHhWLXiGhN4UTSCXv_n1ArDnxTLFBroRS8dxuFBZoD9Mpj10vYFSDDhUfFqjgMqtpr30TpDMfee1wkqB6K757ZSjgCDa0hAbv555GkLdZtRsSgR3xWcxPBsIozqAMFDCWoUCbgTQuA5OiEhhpVco2zv4XLq2sz--VRoBieO12C69KnGRmoLuPtvOayInvrnV96Tbt9fR0fLS2l1nvAdFzVou0SIf9rMZLnURLVQQYE64GR14m-cFRYdUI9vTsFHZBl5w-uCLdzMMofzZaLQ' \
--form 'apkConfiguration=@"path/to/apk-conf-file.apk-conf"' \
--form 'definitionFile=@"<path/to/zip-file-containing-proto-definitions.zip>"'
curl -k --location 'https://<host>:9095/api/deployer/1.2.0/apis/deploy' \
--header 'Host: <host>' \
--header 'Authorization: bearer <access-token>' \
--form 'apkConfiguration=@"path/to/apk-conf-file.apk-conf"' \
--form 'definitionFile=@"<path/to/zip-file-containing-proto-definitions.zip>"'
name: "OrderServiceAPI"
basePath: "/grpcapi"
version: "v1"
type: "GRPC"
defaultVersion: false
subscriptionValidation: false
endpointConfigurations:
    production:
        endpoint: "http://order-backend:6566"
operations:
- target: "order.OrderService"
  verb: "CreateOrder"
  secured: true
  scopes: []
- target: "order.OrderService"
  verb: "ServeOrder"
  secured: true
  scopes: []
- target: "payment.PaymentService"
  verb: "ProcessPayment"
  secured: true
  scopes: []
- target: "user.UserService"
  verb: "GetUser"
  secured: true
  scopes: []

Execute the command below. You will be able to see that the API is successfully deployed.

kubectl get apis -n <namespace>

Invoking a gRPC API

You will need a gRPC backend in order to invoke the API and get a correct response. A sample backend for the Order Service APIs has been provided under this section.

Once your gRPC API has been deployed, you can invoke it either via Postman, a custom client, or the grpcurl command-line tool. You can download the grpcurl tool from here. Code for custom clients can be generated by providing the modified proto file to the Protocol buffer Compiler.

If you are using grpcurl, you can view the various flags needed for sending requests here.

A sample gRPC call is provided below.

grpcurl -insecure \
-import-path /Users/User/proto-files \
-proto common.proto \
-proto user.proto \
-proto payment.proto \
-proto order.proto \
-d '{"id": "1"}' \
-H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsICJ0eXAiOiJKV1QiLCAia2lkIjoiZ2F0ZXdheV9jZXJ0aWZpY2F0ZV9hbGlhcyJ9.eyJpc3MiOiJodHRwczovL2lkcC5hbS53c28yLmNvbS90b2tlbiIsICJzdWI' \
default.gw.wso2.com:9095 grpcapi.v1.user.UserService/GetUser
grpcurl -insecure \
-import-path <path/to/proto/files> \
-proto <file-1.proto> \
-proto <file-2.proto> \
-d '{"argument": value}' \
-H 'Authorization: Bearer <Access-Token>' \
default.gw.wso2.com:9095 <complete-service-and-method-name>