📦
Storage service
  • Introduction
  • How-to: basic operations
    • Ingest a bag into the storage service
    • Look up an already-stored bag in the storage service
    • Look up the versions of a bag in the storage service
  • How to: advanced usage
    • Getting notifications of newly stored bags
  • How to: debugging errors
    • Where to find application logs
    • Manually marking ingests as failed
  • Reference/design decisison
    • The semantics of bags, ingests and ingest types
    • How identifiers work in the storage service
    • How files are laid out in the underlying storage
    • Compressed vs uncompressed bags, and the choice of tar.gz
  • Developer information/workflow
    • An API reference for the user-facing storage service APIs
    • Key technologies
    • Inter-app messaging with SQS and SNS
    • How requests are routed from the API to app containers
    • Repository layout
    • How Docker images are published to ECR
  • Wellcome-specific information
    • Our storage configuration
      • Our three replicas: S3, Glacier, and Azure
      • Using multiple storage tiers for cost-efficiency (A/V, TIFFs)
      • Small fluctuations in our storage bill
      • Delete protection on the production storage service
    • Wellcome-specific debugging
      • Why did my callback to Goobi return a 401 Unauthorized?
    • Recovering files from our Azure replica
    • Awkward files and bags
    • Deleting files or bags bags from the storage service
Powered by GitBook
On this page
  1. Developer information/workflow

How requests are routed from the API to app containers

PreviousInter-app messaging with SQS and SNSNextRepository layout

Last updated 2 years ago

This document explains how requests are routed from a publicly visible HTTP endpoint to our app containers.

  1. A user makes an HTTP request, e.g. GET /ingests.

    This request is sent to API Gateway, either:

    • Through the (e.g. https://ykxcqkp840.execute-api.eu-west-1.amazonaws.com/v1), or

    • Through a attached to the API

  2. API Gateway authorizes the request with Cognito.

    We typically use OAuth2 with the . If Cognito rejects the user's credentials, API Gateway returns an error response.

  3. If the user is authorized, API Gateway forwards the request to a network load balancer (NLB).

    This NLB is running inside a private VPC, which isn't accessible from the Internet. API Gateway uses a to connect to the NLB.

    API Gateway uses two different ports to distinguish between the APIs.

    • If the request is for the bags API, it forwards the request to port 65534.

    • If the request is for the ingests API, it forwards the request to port 65535.

  4. The NLB looks at the request, and applies two listener rules:

    • If this request is on port 65534 (bags API), forward it to the bags target group

    • If this request is on port 65535 (ingests API), forward it to the items target group

  5. The routes the request to one of the registered targets.

    In this case, the targets are ECS tasks running either the bags API or the ingests API. When the task starts, it tries to register with the target group. The target group runs some health checks to ensure the task can process requests before it becomes "registered" and is used to serve requests.

    If there are multiple tasks running, the target group distributes requests between them.

    Requests are routed to an externally published port on the ECS task; in this case, port 9000.

  6. Within the ECS task, we run two containers:

    • The app container (e.g. bags_api, ingests_api)

    • An nginx container

    Requests from the target group are initially routed to the nginx container, and then passed to the app container. The separate nginx container lets us apply some HTTP-specific config that's shared among all our apps (e.g. CORS).

    The nginx container runs on port 9000; the app container runs on port 9001. Only port 9000 is externally accessible.

API's Invoke URL
custom domain name
client credentials flow
VPC Link
target group