Serving Web Resources
This guide provides a simple example of how to serve arbitrary web resources like .html
files.
To use proto files from artifacts in your schema, you need to adjust your maven build definition:
- Java
-
<includeDependenciesInDescriptorSet>true</includeDependenciesInDescriptorSet>
- Scala
-
For sbt builds, this works out-of-the-box with loading proto files from artifacts.
Next, import HttpBody
and build your Kalix service to return that:
- Java
-
syntax = "proto3"; package com.example; import "google/protobuf/empty.proto"; import "google/api/annotations.proto"; import "google/api/httpbody.proto"; (1) import "kalix/annotations.proto"; message File { string file = 1; } message FileInDir { string file = 1; string directory = 2; } service FileService { option (kalix.codegen) = {action: {}}; option (kalix.service).acl.allow = { principal: ALL }; rpc IndexHtml(google.protobuf.Empty) returns (google.api.HttpBody) { option (google.api.http) = { get: "/" (2) }; }; rpc GetFile(File) returns (google.api.HttpBody) { (3) option (google.api.http) = { (4) get: "/site/{file}" (5) }; }; rpc GetFileInDir(FileInDir) returns (google.api.HttpBody) { option (google.api.http) = { get: "/site/{directory}/{file}" (6) }; }; }
1 Use import
to use proto files from dependencies.2 Serve the index.html
under/
.3 Choose google.api.HttpBody
as the return type.4 Enable HTTP endpoints using google.api.http
.5 Serve files in like web/index.js
under/site/index.js
.6 Optional: serve files in directories, e.g. web/img/favicon.png
under/site/img/favicon.png
. - Scala
-
syntax = "proto3"; package com.example; import "google/protobuf/empty.proto"; import "google/api/annotations.proto"; import "google/api/httpbody.proto"; (1) import "kalix/annotations.proto"; message File { string file = 1; } message FileInDir { string file = 1; string directory = 2; } service FileService { option (kalix.codegen) = {action: {}}; option (kalix.service).acl.allow = { principal: ALL }; rpc IndexHtml(google.protobuf.Empty) returns (google.api.HttpBody) { option (google.api.http) = { get: "/" (2) }; }; rpc GetFile(File) returns (google.api.HttpBody) { (3) option (google.api.http) = { (4) get: "/site/{file}" (5) }; }; rpc GetFileInDir(FileInDir) returns (google.api.HttpBody) { option (google.api.http) = { get: "/site/{directory}/{file}" (6) }; }; }
1 Use import
to use proto files from dependencies.2 Serve the index.html
under/
.3 Choose google.api.HttpBody
as the return type.4 Enable HTTP endpoints using google.api.http
.5 Serve files in like web/index.js
under/site/index.js
.6 Optional: serve files in directories, e.g. web/img/favicon.png
under/site/img/favicon.png
.
Use effects().reply
effects.reply
to serve content (e.g. by loading a file from disk with) a 200
HTTP response:
- Java
-
InputStream inputStream = getClass().getResourceAsStream(fullPath); if(null == inputStream) { throw new NoSuchFileException("File " + fullPath + " not found"); } byte[] byteArray = inputStream.readAllBytes(); String contentType = getContentTypeByFile(file); HttpBody response = HttpBody.newBuilder() .setContentType(contentType) .setData(ByteString.copyFrom(byteArray)) .build(); LOG.info("Serving {} with {}", fullPath, contentType); Metadata header = Metadata.EMPTY.add("Cache-Control", "no-cache"); return effects().reply(response, header);
- Scala
-
val byteArray = getClass().getResourceAsStream(fullPath).readAllBytes() val contentType = contentTypeByFile(file) log.info(s"Serving $fullPath with $contentType") val header = Metadata.empty.add("Cache-Control", "no-cache") effects.reply(new HttpBody(contentType, ByteString.copyFrom(byteArray)), header)
The example also shows how to return additional HTTP headers.
Use effects().ignore
effects.ignore
to serve a 404
HTTP response:
- Java
-
return effects().ignore();
- Scala
-
effects.ignore
Use effects().error
effects.error
to serve a 500
HTTP response:
- Java
-
return effects().error("500: Not able to serve {}" + fullPath);
- Scala
-
effects.error(s"Not able to serve $file")