A Gateway resource exposes services to the outside world and is used often in production environments. From the docs:
A Gateway describes an instance of traffic handling infrastructure. It defines a network endpoint that can be used for processing traffic, i.e. filtering, balancing, splitting, etc. for backends such as a Service. For example, a Gateway may represent a cloud load balancer or an in-cluster proxy server that is configured to accept HTTP traffic.

In the diagram above, the "client" can be anything. It doesn't live inside k8s. It might just be a web browser or a mobile app. The "Gateway-managed load balancer" can be a bit confusing, we'll talk about it more later. For now, just know that it's a load balancer that lives outside the cluster and routes traffic through the Gateway to a service.
Gateway is the newer alternative to Ingress which you might still come across in production systems.
The Gateway API is a spec that has different implementations. We're gonna use the Envoy Gateway, which you can install with this command:
kubectl apply --server-side -f https://github.com/envoyproxy/gateway/releases/download/v1.5.1/install.yaml
Then, create a file that we'll call app-gatewayclass.yaml because we want to create a Gateway for the entire synergychat application, not just a specific service.
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: app-gatewayclass
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
We need this GatewayClass because:
controllerName is set to the one created while installing the Envoy GatewayNext, create the actual Gateway in new file named app-gateway.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: app-gateway
spec:
gatewayClassName: app-gatewayclass
listeners:
- name: http
protocol: HTTP
port: 80
Next, we need to define the routing rules for our Gateway with HTTPRoute resources. Set a rule for the web service, which we could save in a file named web-httproute.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web-httproute
spec:
parentRefs:
- name: app-gateway
hostnames:
- "synchat.internal"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: web-service
port: 80
... and another for the API service in api-httproute.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-httproute
spec:
parentRefs:
- name: app-gateway
hostnames:
- "synchatapi.internal"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: api-service
port: 80
This says that any traffic to the synchat.internal domain name should be routed to the web-service and any traffic to synchatapi.internal domain name should be routed to the api-service.
Apply all the resources, then run:
kubectl proxy
Run and submit the CLI tests.