Invoke services

You can invoke services that have been deployed to Akka Serverless in the following ways:

Exposing services to the internet

Akka Serverless allows you to expose your services to the internet, using routes.

A route declares how traffic to a particular hostname gets routed to your services. You can let Akka Serverless generate a hostname for you, or you can provide your own hostname at your own domain. If you want to use your own hostname, you’ll need to register your domain and configure your Domain Name System (DNS) settings using a third party DNS service.

All traffic to Akka Serverless uses Transport Layer Security (TLS). Akka Serverless will automatically provision a certificate for you using Let’s Encrypt. The certificate is provisioned whether you use an Akka Serverless provided hostname, or bring your own.

Exposing a single service

If you have a single service you want to expose to the internet using an Akka Serverless generated hostname, you can do so using the akkasls service expose command. This command is provided as a convenience, particularly when you’re getting started with Akka Serverless:

$ akkasls service expose my-service
Service 'my-service' was successfully exposed at: spring-tooth-3406.us-east1.akkaserverless.app

You can now access your service using the hostname described in the output of the command above. For example, if creating a gRPC client for the above service, you need to configure it to send requests to spring-tooth-3406.us-east1.akkaserverless.app:443.

You also have the option of enabling Cross-Origin Resource Sharing (CORS) for the service, using the --enable-cors flag.

Managing routes

Routes give you the ability to to direct incoming traffic to a single hostname to more than one service. To manage this, you can use the akkasls routes command. Before you create a route, you need to provision a hostname.

Provisioning a custom hostname

If you want to provision a custom hostname, you first need to register it with your project. Only one project can use a given hostname. Let’s say the hostname you want to register is called akka-services.mycompany.com. To register a hostname, use the akkasls project hostname add command:

$ akkasls project hostname add akka-services.mycompany.com
HOSTNAME                      GENERATED   REGION     CNAME
akka-services.mycompany.com   false       us-east1   us-east1.akkaserverless.app
Notice the CNAME value above, this tells you what you need to point your hostname to. You will need to create a CNAME record for akka-services.mycompany.com that points to us-east1.akkaserverless.app with your DNS provider. Akka Serverless will not provision any routes for this hostname until your DNS configuration is correct. Note, it can take up to 24 hours for DNS changes to take effect, depending on your DNS provider.

Provisioning a generated hostname

If you do not want to bring your own hostname, you can let Akka Serverless generate one for you, by running akkasls project hostname add with no arguments:

$ akkasls project hostname add
HOSTNAME                                      GENERATED   REGION     CNAME
young-fire-2481.us-east1.akkaserverless.app   true        us-east1

This shows the hostname that was just generated for you. You will need this when you create your route.

Creating routes

Let’s assume you want to expose two gRPC services:

  1. shopping-cart, which has a gRPC service called acme.ecommerce.ShoppingCart

  2. product-info, which has a gRPC service called acme.ecommerce.ProductInfo

The path that a gRPC service is served at is the fully qualified name of the service. For example, the example.ecommerce.ShoppingCart will have a path of /example.ecommerce.ShoppingCart.

Let’s also assume that you want to name the route acme-ecommerce, and that the hostname you want to serve it at is ecommerce.acme.org, and that you’ve already added this route to the project following the instructions above.

We can now create the route:

akkasls route create acme-ecommerce \
  --hostname ecommerce.acme.org \
  --path /example.ecommerce.ShoppingCart=shopping-cart \
  --path /example.ecommerce.ProductInfo=product-info

Having created it, we can now get its status by listing all routes:

$ akkasls route list
NAME             HOSTNAME             PATHS                     CORS ENABLED   STATUS
acme-ecommerce   ecommerce.acme.org   /example.ecommerce.Sho…   false          DnsNotVerified

Note above that the status is DnsNotVerified. This indicates that the DNS configuration for our custom hostname is not correct. More details can be obtained by getting details for the route:

$ akkasls route get acme-ecommerce
Route: 	acme-ecommerce
Host: 	ecommerce.acme.org

Paths:
         /example.ecommerce.ShoppingCart   shopping-cart
         /example.ecommerce.ProductInfo    product-info

Status:
	HostValidation: False
		Last Transition: 	Tue Nov  9 16:45:53 2021
		Reason: 	DnsNotVerified
		Message: 	Host ecommerce.acme.org did not resolve to a CNAME record. It must be configured to be a CNAME record to us-east1.akkaserverless.app
	Ready: False
		Last Transition: 	Tue Nov  9 16:45:53 2021
		Reason: 	Validating
		Message: 	Validating hostname

Here you can see the exact error message - your hostname is not resolving. To rectify this, you would need to go to your DNS provider and update the DNS record for the host, and then wait for that change to propagate. Once the problem is fixed, there is nothing you need to do, Akka Serverless will periodically recheck the DNS configuration to see if it’s updated, typically every 20 minutes. Note that DNS configuration can be cached in DNS servers for up to 24 hours, so it may take that long before Akka Serverless can see your changes.

Updating routes

Routes can be updated using the akkasls route update command. For example, to remove the product info service from the route, and also add a inventory service, you might run:

akkasls route update acme-ecommerce \
  --remove-path /example.ecommerce.ProductInfo \
  --path /example.ecommerce.Inventory=inventory

Working with route descriptors

You may want to specify your routes using a descriptor. Descriptors can be checked into source control, allowing you to version your routing configuration. This can be useful if you have complex routes.

You can export an existing route using the akkasls route export command, this will output the descriptor in YAML format:

$ akkasls route export acme-ecommerce
corsPolicy:
  allowMethods:
  - GET
  - POST
  allowOrigins:
  - https://www.acme.org
host: ecommerce.acme.org
routes:
- prefix: /example.ecommerce.ShoppingCart
  route:
    service: shopping-cart
- prefix: /example.ecommerce.ProductInfo
  route:
    service: product-info

To save the output of the command to a YAML file, you can run the command below:

akkasls route export acme-ecommerce > acme-commerce-routes.yaml

To use this descriptor to either create or update a route, you can pass the file name using the -f flag:

akkasls route update acme-ecommerce -f acme-ecommerce-route.yaml

You can also edit the route descriptor in place using the akkasls route edit command. This will open the route descriptor in the editor configured in the EDITOR environment variable, allowing you to edit and save it. On exiting the editor, the route will be updated:

$ akkasls route edit acme-ecommerce
Route updated.

Enabling CORS

CORS can be enabled by configuring at least one allowed origin, for example:

akkasls-dev route update acme-ecommerce --cors-origin https://www.acme.org

Securing routes

All routes are served with TLS certificates. In addition, you can also enable client certificate authentication, also known as Mutual TLS (mTLS). Instructions for doing this can be found in Securing services.

Testing and development

During testing and development, you can either use the akkasls proxy command, or the Service Explorer in the Akka Serverless console, to invoke your services.

Currently, the better user experience comes from the akkasls proxy command, even if you prefer a graphical UI for exploring your services, as the proxy command includes a web based graphical UI that it runs on your local machine. We recommend using this for all testing and development invocations of services.

akkasls proxy command

The akkasls proxy command starts a proxy running locally on your machine that forwards all requests it receives to your service, via a mechanism that authenticates you as having access to manage the service, so that you can access it without exposing it to the internet. This can be used for ad-hoc invocations of your service for testing and debugging purposes, as well as by other services running locally on your machine for integration testing purposes.

In addition, it also offers a built in web based gRPC explorer that provides both form and JSON based mechanisms for creating messages, allows setting custom headers, and stores a history of prior invocations for reuse.

Only unary requests are supported by the akkasls proxy. Server streamed requests may work if your service writes the entire stream and then immediately closes the response, however client streamed requests will not work. The exception to this is the gRPC reflection API, for which special handling has been implemented so that gRPC clients that use server reflection will work.
Do not use the akkasls proxy command as a mechanism for tunneling requests from other systems. Invocations through the proxy are subject to quotas that, when exceeded, could temporarily block you from being able to manage your project. This feature is only intended for testing and development.

Starting the proxy

The proxy can be started by running the following:

akkasls service proxy my-service

This will start the proxy on port 8080 bound to localhost. The proxy runs in the foreground, and will log the requests made through it as it receives them. You can stop the proxy by hitting Ctrl+C.

You can customize the port and bind address by running:

akkasls service proxy my-service --port 8081 --bind-address 0.0.0.0

You can now invoke your services using an HTTP or gRPC client. TLS is not enabled, so it’s important to configure gRPC clients to use plaintext connections. So for example, using grpcurl to invoke your services from another terminal window:

grpcurl -plaintext -d '{"cartId":"my-cart"}' localhost:8080 \
 com.example.shoppingcart.ShoppingCartService.GetCart

If you are using Akka Serverless’s HTTP to gRPC transcoding support, you can also invoke them as a REST API, for example using curl:

curl http://localhost:8080/carts/my-cart

Using the built in graphical client

The akkasls command can also start a graphical client, which embeds grpcui in the proxy, allowing you to easily explore your services and build and make requests on them. To enable it, use the --grpcui flag:

akkasls service proxy my-service --grpcui

A web browser will automatically be opened for you on the gRPC UI explorer page served by the proxy:

The gRPC UI explorer

The Service Explorer

The Service Explorer requires your services to be exposed to the internet in order to use it. If you want to have a graphical way to explore and invoke your services without exposing them to the internet, use the akkasls proxy command instead.

You can access the Service Explorer by clicking on:

  • The link in the left navigation bar after you select a service

  • The link in the top menu after you select a service

  • Any of the methods in the Service Explorer pane of the service overview window

The Service Explorer inspects your API definition and generates commands for:

  • grpcURL

  • cURL

  • fetch

Additionally, it also shows the Protocol Buffer format

To use the Service Explorer to call a service:

  1. Select the method you want to invoke

  2. Choose how you want to invoke it

  3. Fill in the payload details

  4. Click the copy command button

  5. Paste the command in a terminal window

service explorer