Как настроить кеширование Varnish для GraphQL в Django

Вот мой проект django-benchmark, в котором я реализовал простые конечные точки REST API и GraphQL. Перед своим приложением я поставил Varnish для кэширования. Кэширование хорошо работает для конечных точек Rest HTTP и не работает для GraphQL, вот моя конфигурация Varnish. Что я делаю не так?

vcl 4.1;

# Default backend definition. Set this to point to your content server.
backend default {
    .host = "0.0.0.0";
    .port = "8080";
}

sub vcl_hash {
    # For multi site configurations to not cache each other's content
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }
    
    # Cache GET requests coming to endpoint located at /api/graphql
    if (req.method == "POST" && req.url ~ "/api/graphql") {
        call process_graphql_headers;
    }
}

# TODO: Find way to cache GraphQL requests.
sub process_graphql_headers {
}

sub vcl_recv {
    # # Bypass authenticated requests, these requests should not be cached by default
    # if (req.http.Authorization ~ "^Bearer") {
    #     return (pass);
    # }
}

sub vcl_backend_response {
}

sub vcl_deliver {
}

Настройка приложения

Настройте проект и базу данных семян.

$ git clone https://github.com/ldynia/django-benchmark.git
$ cd django-benchmark/
$ docker-compose up -d
$ docker exec -it django-benchmark python manage.py seed 100

Тестирование приложений

Запросить конечную точку graphql напрямую (порт 8080) или сначала пройти через лак (порт 8888).

# Query graphql endpoint directly
$ curl 'http://localhost:8080/api/graphql/' \
  -X 'POST' \
  -H 'Content-Type: application/json' \
  --data-raw '{"query":"query { allDummy { results { id } }}"}'

# Query graphql endpoint hitting varnish first
$ curl 'http://localhost:8888/api/graphql/' \
  -X 'POST' \
  -H 'Content-Type: application/json' \
  --data-raw '{"query":"query { allDummy { results { id } }}"}'

Ответ

{
    "data": {
        "allDummy": {
            "results": [{
                "id": "1"
            }, {
                "id": "2"
            }, {
                "id": "3"
            },
            ...
            ]
        }
    }
}

Заголовки HTTP-запросов и ответов

$ curl 'http://localhost:8888/api/graphql/' -X 'POST' -H 'Content-Type: application/json' --data-raw '{"query":"query { allDummy { results { id } }}"}' -v > /dev/null
Note: Unnecessary use of -X or --request, POST is already inferred.
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 127.0.0.1:8888...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8888 (#0)
> POST /api/graphql/ HTTP/1.1
> Host: localhost:8888
> User-Agent: curl/7.68.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 48
> 
} [48 bytes data]
* upload completely sent off: 48 out of 48 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Mon, 08 Mar 2021 13:45:42 GMT
< Server: WSGIServer/0.2 CPython/3.7.9
< Content-Type: application/json
< Vary: Cookie
< X-Frame-Options: DENY
< Content-Length: 17128
< X-Content-Type-Options: nosniff
< Referrer-Policy: same-origin
< Set-Cookie:  csrftoken=86bgA2o83BavIOTq7Wf59pXxZPeJ65byTMt286UbyKfPSo9O1uefGw8gMP99plbL; expires=Mon, 07 Mar 2022 13:45:42 GMT; Max-Age=31449600; Path=/; SameSite=Lax
< X-Varnish: 32791
< Age: 0
< Via: 1.1 varnish (Varnish/6.4)
< Accept-Ranges: bytes
< Connection: keep-alive
< 
{ [17128 bytes data]
100 17176  100 17128  100    48   124k    358 --:--:-- --:--:-- --:--:--  125k

person Lukasz Dynowski    schedule 04.03.2021    source источник
comment
apollographql.com/blog/   -  person xadm    schedule 05.03.2021
comment
@xadm То есть кэширование на стороне сервера для GraphQL практически отсутствует?   -  person Lukasz Dynowski    schedule 05.03.2021
comment
По сути, это не простая/просто разрешимая проблема... stackoverflow.com/a/65513275/6124657   -  person xadm    schedule 05.03.2021
comment
Все зависит от того, чего вы пытаетесь достичь. Я вижу пользовательские заголовки запросов, такие как Store и Content-Currency, используемые в качестве вариантов кеша. Какова их цель? Я также вижу, что кеш обходится, если используется аутентификация Bearer. Использует ли ваш сервис GraphQL такую ​​аутентификацию? Что нужно кэшировать? только запросы GET? Или POST запросы тоже? Требуется ли самоанализ тела запроса и ответа? Мне понадобится гораздо больше информации, прежде чем я смогу помочь вам с кодом VCL.   -  person Thijs Feryn    schedule 05.03.2021
comment
@ThijsFeryn Я отредактировал конфигурацию VCL и избавился от пользовательских заголовков - в конце концов, они мне не нужны. Я хотел бы кэшировать запросы GraphQL, поступающие через метод http GET, назначенный конечной точке /api/graphql. Требуется ли самоанализ тела запроса и ответа? Думаю, я хотел бы провести самоанализ только запроса. Меня в данный момент не волнует тело.   -  person Lukasz Dynowski    schedule 05.03.2021
comment
@LukaszDynowski Пожалуйста, добавьте полный HTTP-запрос GraphQL и соответствующий HTTP-ответ на свой вопрос. Также укажите критерии тела запроса, по которым вы хотите выполнить фильтрацию, и я предложу вам шаблон VCL.   -  person Thijs Feryn    schedule 05.03.2021
comment
@ThijsFeryn Я обновил свой вопрос о том, что вы просили. Кроме того, я включил инструкции по настройке проекта и тестированию конечных точек приложения. Этого достаточно?   -  person Lukasz Dynowski    schedule 08.03.2021