Endpoints

Endpoints in UCF are communication interfaces to the microservices. UCF classifies endpoints into two types:

  • Ingress endpoints - Server side of the communication interface i.e. a server in a microservice listening for connections.

  • Egress endpoints - Client side of the communication interface i.e. a client in a microservice initiating a connection to a server.

UCF endpoints are related to server and client roles and NOT to the data flow direction. It thus follows that an Egress endpoint connects to an Ingress endpoint.

Egress endpoints are only virtual in nature. However, they serve an important job of representing external endpoints / APIs that a microservice depends on and connects to. They are also used to abstract the connection details (address and port) in the client microservice as explained in Creating a Microservice. In an UCF application, when an Egress endpoint of an client microservice is connected to an Ingress endpoint, the connection details (address and port) of the Ingress endpoint are set on the client microservice during application build.

Because of the abstraction explained above:

  • Client microservice does not need to know the connection details of the Ingress endpoint beforehand during microservice development. So microservices can be developed independently.

  • A microservice that implements the Ingress endpoint can be easily replaced by another microservice that implements a similar compatible Ingress endpoint.

Endpoint Type

Description

HTTP

https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md

gRPC

https://developers.google.com/protocol-buffers/docs/proto3

RTSP

https://www.rfc-editor.org/rfc/rfc2326.html

AsyncIO

https://github.com/asyncapi/spec/blob/v2.2.0/spec/asyncapi.md

UCX

RESP

https://github.com/asyncapi/spec/blob/v2.2.0/spec/asyncapi.md

MongoDB Wire

Raw UDP / TCP

Raw UDP / TCP

For UCF compliant microservices, each Ingress or Egress endpoint is accompanied by an endpoint definition file which describes the data exchange format expected by the endpoint. The format of endpoint definition file depends on the scheme the endpoint follows. The endpoint schemes are described in detail in the below section.

Ingress Endpoints

Ingress endpoints in UCF are described using the following attributes:

Field

Description

name

A string identifier for the ingress endpoint

description

A short description of the endpoint

scheme

Scheme the endpoint follows

data-flow

Flow of data through the egress endpoint. One of in, out or in-out

service

Server address or Kubernetes service abstraction name for the endpoint.

port

Port number for the ingress endpoint.

protocol

The network protocol the endpoint must use. Either TCP or UDP.

Egress Endpoints

Egress endpoints in UCF are described using the following attributes:

Field

Description

name

A string identifier for the egress endpoint

description

A short description of the endpoint

protocol

The network protocol the endpoint must use. Either TCP or UDP

scheme

Scheme the endpoint follows

mandatory

Boolean indicating if connecting the egress endpoint is mandatory for the microservice to work correctly

data-flow

Flow of data through the egress endpoint. One of in, out or in-out

UCF Endpoint Schemes

HTTP

Represented by string enum http. It is to be used by endpoints that communicate using the HTTP protocol.

The endpoint definition file for HTTP endpoint scheme must follow the OpenAPI v3.0.3 specification - https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md. The file can be in YAML or JSON format and must have the filename <endpoint-name>.yaml or <endpoint-name>.json respectively.

A sample endpoint definition file:

openapi: 3.0.0
info:
  title: MyService API spec
  description: MyService HTTP API
  version: 0.0.1
paths:
  /hello:
    get:
      responses:
        '200':
          description: Success response to the /hello API
      description: Check if the API is up

gRPC

Represented by string enum grpc. It is to be used by endpoints that communicate using the gRPC protocol.

The endpoint definition file for gRPC endpoint scheme must follow the Protocol Buffer Language specification - https://developers.google.com/protocol-buffers/docs/proto3. It is basically the .proto file used in the gRPC client / server implementation and must have the filename <endpoint-name>.proto.

A sample endpoint definition file:

syntax = "proto3";

service PingTest {
  rpc Ping (PingRequest) returns (PingReply) {}
}

message PingRequest {
  string test_message = 1;
}

message PingReply {
  string status = 1;
}

AsyncIO

Represented by string enum asyncio. It is to be used by endpoints that communicate using the Asynchronous events such as using Kafka or MQTT message brokers.

The endpoint definition file for AsyncIO endpoint scheme must follow the AsyncAPI v2.2.0 specification - https://github.com/asyncapi/spec/blob/v2.2.0/spec/asyncapi.md The file can be in YAML or JSON format and must have the filename <endpoint-name>.yaml or <endpoint-name>.json respectively.

A sample endpoint definition file:

asyncapi: 2.2.0
info:
  title: AsyncIO API schema for myservice-ping endpoint
  version: 0.0.1
channels:
  ping:
    publish:
      message:
        payload:
          type: string
          pattern: PING

RTSP

Represented by string enum rtsp. It is to be used by endpoints that use RTSP for streaming data.

The endpoint definition file for RTSP endpoint scheme must follow the JSON schema:

{
    "$schema": "http://json-schema.org/draft-07/schema",
    "$id": "ucf-rtsp-ep-1.0.0",
    "title": " UCF RTSP Endpoint",
    "description": "The object defines UCF RTSP Endpoint Specification",
    "type": "object",
    "required": [
        "mediaPath"
    ],
    "properties": {
        "mediaPath": {
            "description": "Streaming Media Path",
            "type": "string"
        },
        "user": {
            "description": "Username for accessing the RTSP server",
            "type": "string"
        },
        "password": {
            "description": " Password for accessing the RTSP server",
            "type": "string"
        }
    }
}

The file can be in YAML or JSON format and must have the filename <endpoint-name>.yaml or <endpoint-name>.json respectively.

A sample endpoint definition file:

{
    "mediaPath": "/test"
}

RESP

Represented by string enum resp. It is to be used by endpoints that communicate using the Asynchronous events via Redis over RESP (REdis Serialization Protocol). The endpoint definition file for RESP endpoint scheme must follow the AsyncAPI v2.2.0 specification - https://github.com/asyncapi/spec/blob/v2.2.0/spec/asyncapi.md The file can be in YAML or JSON format and must have the filename <endpoint-name>.yaml or <endpoint-name>.json respectively.

A sample endpoint definition file:

asyncapi: 2.2.0
info:
  title: AsyncIO API schema for myservice-ping endpoint
  version: 0.0.1
channels:
  ping:
    publish:
      message:
        payload:
          type: string
          pattern: PING

UCX

Represented by string enum ucx. It is to be used by endpoints that communicate over UCX.

Endpoint definition file for the UCX endpoints are not required

MongoDB Wire

Represented by string enum mongodb-wire. It is to be used by endpoints that communicate using MongoDB Wire Protocol.

Endpoint definition file for the MongoDB Wire endpoints are not required.

Raw UDP / TCP

Represented by string enum none. It is to be used by endpoints that implement some other scheme on top of TCP/UDP e.g. MongoDB Wire Protocol or using raw UDP packets / TCP sockets.

It is NOT mandatory to specify an endpoint definition file for this scheme for the microservice to be UCF compliant.

If specified, the endpoint definition file for this endpoint scheme must follow the JSON schema:

{
    "$schema": "http://json-schema.org/draft-07/schema",
    "$id": "ucf-tcp-udp-ep-1.0.0",
    "title": " UCF TCP/UDP Endpoint",
    "description": "The object defines UCF TCP/UDP Endpoint Specification",
    "type": "object",
    "required": [
        "transportProtocol"
    ],
    "properties": {
        "transportProtocol": {
            "description": "Protocol for data transport. e.g. RTP / RAW etc",
            "type": "string"
        },
        "mediaType": {
            "description": "Type of media audio/video",
            "type": "string"
        },
        "mediaFormat": {
            "description": "Media Format e.g. h264/aac/raw",
            "type": "string"
        },
        "multicast": {
            "description": "Unicast or Multicast mode",
            "type": "string"
        }
    }
}

The file can be in YAML or JSON format and must have the filename <endpoint-name>.yaml or <endpoint-name>.json respectively.

A sample endpoint definition file:

{
    "transportProtocol": "RTP"
}

Endpoint Connections & Validation

As mentioned initially, a connection in an UCF application represents a connection between an Egress endpoint of a client microservice and Ingress of a server microservice.

In the textual representation, connections are specified under the connections field of the application in the format <client-microservice-name-with-egress-endpoint>/<egress-endpoint-name>: <server-microservice-name-with-ingress-endpoint>/<ingress-endpoint-name>.

Following is an example of a connection in an application:

connections:
    hello-client/http-api: hello-server/http-api

In the visual representation (UCF Studio), connections are represented as lines connecting two ports (endpoints). The connections (lines) are color-coded. Different colors are used based on the scheme of the endpoints it connects.

UCF application building tools UCF Application Builder CLI and UCF Studio perform basic endpoint connection validation. They validate if the scheme and protocol is the same for the Ingress and Egress endpoints of a connection.

Egress Endpoint with Multiple Connections

Some Egress endpoints might allow connecting to multiple Ingress endpoints. This is indicated if the egress endpoint has multi field set to true.

In textual representation, multiple connections can be specified in the format -

<microservice-name-with-egress-endpoint>/<egress-endpoint-name>: [
    <microservice-name-with-ingress-endpoint1>/<ingress-endpoint-name1>,
    <microservice-name-with-ingress-endpoint2>/<ingress-endpoint-name2>
]

Following is an example:

connections:
    hello-client/http-api: [ hello-server/http-api, some-other-server/http-api ]

External Endpoints

In some applications, some client microservices might want to connect to an service / endpoint that is not part of the application. For instance, the service might be hosted externally.

For this purpose, UCF provides a pseudo microservice ucf.svc.external-endpoint that can be added to applications. It has an Ingress endpoint named endpoint to which Egress endpoints of client microservices can be connected.

An example of usage of the pseudo microservice ucf.svc.external-endpoint in an UCF application is shown below:

components:
- name: hello-client
  type: ucf.svc.hello-client

- name: hello-server
  type: ucf.svc.external-endpoint
  parameters:
      service: 10.123.2.123
      port: 8080

connections:
    hello-client/http-api: hello-server/endpoint

No connection validation is performed when ucf.svc.external-endpoint is part of the connection. The only job of hello-server component is to set the service address 10.123.2.123 and port 8080 on the client microservice hello-client.