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
anduser
- Basepath:
/grpcapi
- Version:
v1
. - Therefore, the package string in the proto files should be
grpcapi.v1.<package_name>
. Here, it isgrpcapi.v1.order
,grpcapiv1.payment
andgrpcapi.v1.user
.
- Package names:
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>