<p>I am learning Kubernetes. I have Apollo-express GraphQL API, React frontend and React Native app. How do I connect (or) what service type should I use if I want GraphQL API to be able to connect with both frontend and mobile apps?</p>
<p>I got a route <code>/hi</code> that replies <code>Hi!</code> to check if it's up:</p>
<pre><code>app.get('/hi', function (_req, res) {
  res.send('Hi!')
})
</code></pre>
<p>Here's my attempt for <code>api.yaml</code>:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: server-api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: server-api
  template:
    metadata:
      labels:
        app: server-api
    spec:
      terminationGracePeriodSeconds: 5
      containers:
        - name: server-api
          imagePullPolicy: IfNotPresent
          image: my/server-api:latest
          ports:
            - name: gql
              containerPort: 8081
          env:
            - name: NODE_ENV
              value: &quot;development&quot;
            - name: REDIS_HOST
              value: &quot;redis-cache&quot;
            - name: REDIS_PORT
              value: &quot;6379&quot;
            - name: POSTGRES_URL
              valueFrom:
                secretKeyRef:
                  name: postgres-url
                  key: POSTGRES_URL
---
apiVersion: v1
kind: Service
metadata:
  name: server-api
spec:
  type: ClusterIP
  selector:
    app: server-api
  ports:
  - name: gql
    port: 8081
    targetPort: 8081
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: server-api-external
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - http:
        paths:
          - path: /api
            backend:
              serviceName: server-api
              servicePort: 8081
</code></pre>
<p>Minikube IP is <code>192.168.99.100</code>. But it shows <code>Cannot GET /</code> at <code>192.168.99.100/api/hi</code>.</p>
<p>What I am doing wrong?</p>

Swix
<p>Your ingress is incorrect.
With your ingress, when there is incoming request to <code>/api/hi</code>, ingress will match with <code>/api</code> path rule and rewrite the path to <code>/</code> acording to <code>rewrite-target</code> annotation.</p>

<p>To make it work you need to use the folowing ingress:</p>

<pre><code>apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: server-api-external
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - http:
        paths:
          - path: /api/(.*)
            backend:
              serviceName: server-api
              servicePort: 8081
</code></pre>

<p>Now a little explaination on how this works.
Notice changes in <code>path</code> field and <code>rewrite-target</code> annotation.
With this ingress, when there is incoming request to <code>/api/hi</code>, ingress will match <code>/api/(.*)</code> path rule, and then will extract whatever matches with <code>(.*)</code> group (that would be <code>hi</code> in this case). Next, ingress will use this matched group and rewrite the path to <code>/$1</code>, so <code>/</code> + <code>first group match</code>. At the end the path that your application receives will be <code>/hi</code> and this is what you are looking for.</p>

<p>Refer to <a href="https://kubernetes.github.io/ingress-nginx/examples/rewrite/" rel="nofollow noreferrer">Nginx Ingress Controller documantation</a> for more detailed explaination of rewrite feature.</p>

<p>Let me know if something is not clear enough and needs more explaination.</p>
