blob: b4bf76ae59088b47b484de7b4ac61bd5bed9991a [file] [log] [blame] [view]
# Service capabilities
Caution: service capabilities are experimental and in development. Their
behavior and APIs could change at any time.
A [service capability][glossary.service-capability] is a capability that
enables discovery of one or more individually named
[FIDL service][glossary.service] instances. Service capabilities are backed by
a [glossary.channel] that speaks the [`Directory`][directory.fidl] protocol,
where each entry in the directory exposes a named [service instance](#instances).
```fidl
library fuchsia.examples;
const MAX_STRING_LENGTH uint64 = 32;
@discoverable
protocol Echo {
EchoString(struct {
value string:MAX_STRING_LENGTH;
}) -> (struct {
response string:MAX_STRING_LENGTH;
});
SendString(struct {
value string:MAX_STRING_LENGTH;
});
-> OnString(struct {
response string:MAX_STRING_LENGTH;
});
};
service EchoService {
regular_echo client_end:Echo;
reversed_echo client_end:Echo;
};
```
Note: For more details on FIDL service syntax, see the
[FIDL language reference][fidl-reference].
Service implementations are served from provider components using the
[outgoing directory][glossary.outgoing-directory] and consumed from another
component's [namespace][glossary.namespace].
## Service instances {#instances}
Multiple named instances of a service can be hosted by a single component.
These are present in the [namespace][glossary.namespace] of the consuming
component as subdirectories of the service.
The component framework generates an arbitrary, unique identifier for each
service instance name.
For example, if the framework generates `57dfe118a2a8` as the instance name of
the `fuchsia.examples.EchoService` service, a consuming component could connect
to the protocols in that instance using the following namespace paths:
- `/svc/fuchsia.examples.EchoService/57dfe118a2a8/regular_echo`
- `/svc/fuchsia.examples.EchoService/57dfe118a2a8/reversed_echo`
## Providing service capabilities {#provide}
To provide a service capability, a component must declare the capability and
[route](#route) it from `self`. The component hosts the service capability in
its [outgoing directory][glossary.outgoing-directory].
To define the capability, add a `capabilities` declaration for it:
```json5
{
capabilities: [
{
service: "fuchsia.example.ExampleService",
},
],
}
```
This defines a capability hosted by this component whose outgoing directory path
is `/svc/fuchsia.example.ExampleService`. You can also customize the path:
```json5
{
capabilities: [
{
service: "fuchsia.example.ExampleService",
path: "/my_svc/fuchsia.example.MyExampleService",
},
],
}
```
## Routing service capabilities {#route}
Components route service capabilities by [exposing](#expose) them to their
parent and [offering](#offer) them to their children.
For more details on how the framework routes component capabilities,
see [capability routing][capability-routing].
### Exposing {#expose}
Exposing a service capability gives the component's parent access to that
capability:
```json5
{
expose: [
{
service: "fuchsia.example.ExampleService",
from: "self",
},
],
}
```
The `from: "self"` directive means that the service capability is
[provided](#provide) by this component.
#### Dynamic collections
A service capability can be exposed from a [dynamic collection][collection]:
```json5
{
collections: [
{
name: "coll",
durability: "transient",
},
],
expose: [
{
service: "fuchsia.example.ExampleService",
from: "#coll",
},
],
}
```
Note: When routing services exposed from components in the collection, the
component framework renames each [service instance](#instances) with an
arbitrary, unique identifier to allow multiple components in the collection to
expose the same service.
### Offering {#offer}
Offering a service capability gives a child component access to that
capability:
```json5
{
offer: [
{
service: "fuchsia.example.ExampleService",
from: "self",
to: [ "#child-a", "#child_b" ],
},
],
}
```
## Consuming service capabilities {#consume}
To consume a service capability, the component must request the capability and
open the corresponding path in its [namespace][glossary.namespace].
To request the capability, add a `use` declaration for it:
```json5
{
use: [
{
service: "fuchsia.example.ExampleService",
},
],
}
```
This populates the service in the component's namespace at the well-known path
`/svc/fuchsia.example.ExampleService`. You can also customize the path:
```json5
{
use: [
{
service: "fuchsia.example.ExampleService",
path: "/my_svc/fuchsia.example.MyExampleService",
},
],
}
```
For more information about the open request, see
[life of a protocol open][life-of-a-protocol-open].
Note: For a working example of routing a service capability between components,
see [`//examples/components/services`][routing-example].
[glossary.channel]: /docs/glossary/README.md#channel
[glossary.namespace]: /docs/glossary/README.md#namespace
[glossary.outgoing-directory]: /docs/glossary/README.md#outgoing-directory
[glossary.protocol]: /docs/glossary/README.md#protocol
[glossary.service]: /docs/glossary/README.md#service
[glossary.service-capability]: /docs/glossary/README.md#service-capability
[capability-routing]: /docs/concepts/components/v2/capabilities/README.md#routing
[collection]: /docs/concepts/components/v2/realms.md#collections
[fidl-reference]: /docs/reference/fidl/language/language.md
[life-of-a-protocol-open]: /docs/concepts/components/v2/capabilities/life_of_a_protocol_open.md
[directory.fidl]: https://fuchsia.dev/reference/fidl/fuchsia.io#Directory
[realm.fidl]: https://fuchsia.dev/reference/fidl/fuchsia.sys2#Realm
[routing-example]: /examples/components/services