Microservice Routing
Calling a function on a Microservice
Dependencies
Before you can configure Beamable Standalone Microservices, you need to complete the Getting-Started Guide. That means having Dotnet 8 installed, and getting the Beam CLI.
You can confirm you have everything installed checking the versions of the tools.
dotnet --version
beam version # beam --version also works.
In order to configure a Microservice, you also need to have a local .beamable
workspace with a Beamable Standalone Microservice. As a reminder, you can create one quickly using the commands below.
beam init MyProject
cd MyProject
beam project new service HelloWorld
Microservice Routing
Beamable Microservices use a privileged web socket to communicate with Beamable's existing APIs and services. There is a custom Beamable application level protocol, Thorium, that allows a Microservice to receive HTTPS traffic sent to https://api.beamable.com
. However, for the Microservice to receive the traffic, the HTTP request needs to meet the following requirements,
- The
uri
of the HTTP request must have apath
that maps to the desired Microservice. - The HTTP request must have an
X-DE-SCOPE
header, and - Optionally, the HTTP request should have an
Authorization
header that carries a Bearer Token.
Path Routing
The uri
of the HTTP request destined for a Microservice must follow a strict format. The format is given by the code snippet below.
var uri = 'https://' + host + '/basic/' + cid + '.' + pid + '.' + localPrefix + 'micro_' + serviceName + '/' + method;
The variables are described in the following table.
Variable | Required | Example | Description |
---|---|---|---|
host | yes | api.beamable.com | In most cases, the host is always api.beamable.com . However, if you have a Beamable Private Cloud arrangement, this may vary. |
cid | yes | 1338004997867618 | The Customer Id, or CID, is the ID that defines your organization apart from other Beamable developers. |
pid | yes | DE_1752011665993728 | The Project Id, or PID, is the ID that defines your Realm. |
localPrefix | no | Macbook-Pro | A Microservice may run locally on a developer's machine, and it may run remotely deployed to the Beamable Cloud. In this scenario, the two instances should not receive traffic from the same origin. Thus, a prefix is injected into the routing to distinguish between the two services. |
serviceName | yes | HelloWorld | The name of your service. This maps to the Beam Id of your service. |
method | yes | Add | The name of the Method you want to invoke. |
When the host
(api.beamable.com
) receives an HTTP request with the following uri
format, the request will be deconstructed into the variable components, and the contents of the HTTP request will be forwarded to your Microservice via the Thorium web socket protocol. The Microservice receives the request, and uses the method
component of the original request to invoke the right [Callable]
method.
X-DE-SCOPE Header
In addition to specifying the cid
and pid
in the uri
of the HTTP request, those values must also be sent in a special HTTP header, X-DE-SCOPE
. The value for this header should take the format,
var scope = cid + '.' + pid;
Authorization
Finally, while not required, it is important to send an HTTP authorization header in the form of a Bearer token. The bearer token should be a valid access token for a Beamable Player. These tokens can be fetched from the Portal, or you can use the following command to view the token information from a local beamable CLI project.
cat .beamable/temp/connection-auth.json
Beamable does not require that any access token be provided via an authorization header. However, if an authorization header is provided, then Beamable will decorate the request with account information before the request is forwarded to the Microservice. The Microservice itself may enforce the account details to have minimal access permissions. These constraints vary based on the type of [Callable]
attribute you use.
The account information is accessible via the Context.UserId
property when executing the [Callable]
method.
Attribute | Authorization Requirements |
---|---|
[Callable] | None. This method may be invoked when no Authorization is provided. Context.UserId will yield 0. |
[ClientCallable] | A valid player access token is required, and the Context.UserId will yield the calling player's player Id. |
[AdminOnlyCallable] | An access token for a player with the admin role. |
[ServerCallable] | This may be used by requests authenticated with signed requests. However, no player is present. |
Calling Microservice Code From Unity
Microservices can automatically generate client code for the Unity game engine. First, a Unity project needs to be linked to the .beamable
workspace. To do this, use the project add-unity-project command.
beam project add-unity-project <relative-path-to-unity-project>
The given path should be the relative path to the Unity project. If it isn't right, the CLI will offer an explorative search flow to identify a valid Unity project.
After the command has run, there will be a .beamable/linked-projects.json
file. You can review it to double check your project has been added correctly.
MyProject % cat .beamable/linked-projects.json
{
"unityProjectsPaths": [
"../UnityProject"
],
"unrealProjectsPaths": []
}%
When there is a linked project, anytime a Microservice builds, it will automatically generate client code for the Unity project to use. This can be accessed via the BeamContext
.
public async Promise TalkToMicroservice(){
var ctx = await BeamContext.Default.Instance;
var client = ctx.Microservices().HelloWorld();
var sum = await client.Add(1, 2);
}
The automatic client code generation can be disabled when a project builds by modifying the <GenerateClientCode>
option. Learn more in the configuration guide.
Custom Clients
It is possible to use the project oapi command to generate an Open API document and then use open source tools to transpile the document into a client in some other programming language.
The following command will output the Open API document for the service into a file called doc.json
.
beam project oapi --ids HelloWorld | jq '.data.openApi | fromjson' > doc.json
In fact, that command can baked into the Microservice's .csproj
file with a custom build target. This requires that the <SolutionDir>
property is set, which only happens when you run the project from the IDE. See the generate-props command to extend the <SolutionDir>
property outside of IDE use cases.
<Target Name="Build Local OpenAPI File" AfterTargets="Build">
<Exec Command="$(BeamableTool) project oapi --ids HelloWorld | jq '.data.openApi | fromjson' > $(SolutionDir)local/doc.json"/>
</Target>
Then, you can use the open source Open API Generator to build a local javascript client. This snippet uses docker to interact with the generator tool, but you can also use npm
.
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \
-i /local/doc.json \
-g javascript \
--additional-properties=usePromises=true \
-o /local/out/js
In this example, we need to use browserify
to convert the generated client code into a valid browser script.
npm install -g browserify
browserify ./dist/index.js --standalone helloWorld > ../../app/bundle.js
Then, a sample web page might use a similar script to interact with the Microservice.
<html>
<body>
<script src="bundle.js"></script>
<script>
var cid = 'cid';
var pid = 'pid';
var refreshToken = 'redacted';
var localPrefix = 'local';
var serviceName = 'HelloWorld';
var host = 'https://api.beamable.com/basic/' + cid + '.' + pid + '.' + localPrefix + 'micro_' + serviceName;
var client = new helloWorld.ApiClient(host);
client.authentications['scope'].apiKey = cid + '.' + pid;
client.authentications['user'].accessToken = refreshToken
var api = new helloWorld.UncategorizedApi(client);
var args = new helloWorld.AddRequestArgs();
args.a = 2;
args.b = 3;
var opts = {
'addRequestArgs': args
};
api.addPost(opts).then(function(result) {
console.log('got result', result)
});
</script>
</body>
</html>```
Updated 6 months ago