Случаи использования нескольких пользовательских эндпоинтов
Предполагается, что GraphQL открывает единственный эндпоинт для запроса данных. Однако существуют ситуации, когда целесообразнее открывать несколько пользовательских эндпоинтов, каждый из которых представляет настроенную схему. Это позволяет нам обеспечить различное поведение для разных пользователей или приложений, просто переключаясь между эндпоинтами.
Открытие нескольких эндпоинтов в GraphQL не равнозначно REST. В то время как в REST каждый эндпоинт предоставляет доступ к заранее определённому ресурсу или набору ресурсов, каждый из нескольких GraphQL-эндпоинтов по-прежнему будет предоставлять доступ ко всем данным своей схемы, позволяя получать именно то, что нам нужно. Таким образом, это всё ещё стандартное поведение GraphQL, с добавлением возможности доступа к данным из разных схем.
Эта возможность также отличается от schema stitching или federation, которые позволяют объединять несколько источников данных в единый унифицированный граф. При работе с несколькими эндпоинтами мы имеем дело с несколькими схемами. Намерение состоит в том, чтобы работать с ними самостоятельно, а не как с частью более крупной схемы.
Открытие различных схем может предоставить доступ к нескольким независимым графам. Создатель GraphQL Ли Байрон объясняет, когда это может быть полезно:
A good example of this might be if you've company is centered around a product and has built a graphql API for that product, and then decides to expand into a new business domain with a new product that doesn't relate to the original product. It could be a burden for both of these unrelated products to share a single API and two separate endpoints with different schema may be more appropriate.
[...] Another example is [...] - you may have a separate internal-only endpoint that is a superset of your external GraphQL API. Facebook uses this pattern and has two endpoints, one internal and one external. The internal one includes internal tools which can interact with product types.
Давайте рассмотрим дополнительные случаи использования, когда открытие нескольких GraphQL-эндпоинтов имеет смысл.
Раздельное открытие эндпоинтов для администраторов и публичного доступа
Когда мы используем единый граф для всех данных в компании, мы можем контролировать, кто имеет доступ к различным полям нашей GraphQL-схемы, настраивая политики контроля доступа. Например, мы можем настроить поля так, чтобы они были доступны только авторизованным пользователям или пользователям с определённой ролью.
Однако когда есть поля, содержащие конфиденциальную или секретную информацию, которая ни при каких обстоятельствах не должна быть доступна посторонним, нам лучше вообще не открывать эти поля в публичной схеме, а только в приватной схеме, доступ к которой имеет только команда. Эта стратегия защитит наши приватные данные от непреднамеренных проблем, таких как программные ошибки и небрежность при настройке схемы, а также усилит безопасность путём разрешения доступа к приватному эндпоинту только посетителям с определённых IP-адресов.
Таким образом, мы можем создать две отдельные схемы — схемы Admin и Public — и открыть их под эндпоинтами /graphql/admin (с ограничением доступа для посетителей с определённого IP) и /graphql/public (доступный для всех) соответственно.
Ограничение доступа к приватной информации более безопасным способом
Этот раздел является обобщением предыдущего: речь идёт не только о публичном vs. административном, но и о любой ситуации, в которой определённая группа пользователей точно не должна иметь доступ к информации другой группы пользователей.
Например, когда нам нужно создать настроенные схемы для наших разных клиентов, мы можем открыть отдельный пользовательский эндпоинт для каждого из них (/graphql/some-client, /graphql/another-client и т.д.), что может быть безопаснее, чем предоставлять им доступ к единой унифицированной схеме с проверкой через контроль доступа.
Предоставление различного поведения разным приложениям
Мы можем предоставить различное поведение разным приложениям, обращающимся к одному источнику данных.
Например, Reddit выдаёт разный ответ в зависимости от того, обращаемся ли мы с десктопного или мобильного браузера. С десктопного браузера, вне зависимости от того, авторизованы мы или нет, мы можем напрямую просматривать контент:

Однако при доступе с мобильного устройства необходимо авторизоваться для просмотра контента, и нас призывают использовать приложение вместо браузера:

Такое различное поведение можно обеспечить, создав две схемы — схемы Desktop и Mobile — и открыв их под /graphql/desktop и /graphql/mobile соответственно.
Генерация сайта на разных языках
Если мы хотим генерировать один и тот же сайт на разных языках, мы можем включить код языка в структуру пользовательского эндпоинта, например /graphql/en для английского и /graphql/fr для французского. Затем GraphQL-сервер может извлекать эту информацию и переводить данные на нужный язык.
Наконец, мы указываем на каждый из этих эндпоинтов в генераторе статических сайтов, чтобы получить сайт на том или ином языке:

Тестирование обновлённой схемы перед выпуском в продакшн
Если мы хотим обновить нашу GraphQL-схему и дать возможность группе пользователей протестировать её заранее, мы можем открыть эту новую схему через эндпоинт /graphql/upcoming. Более того, мы также могли бы открыть эндпоинт /graphql/bleeding-edge, который постоянно разворачивает схему из DEV-окружения.
Поддержка подхода BfF
Backend-for-Frontends (сокращённо BfF) — это подход для создания разных API для разных клиентов, при котором каждый клиент «владеет» своим API, что позволяет ему создавать наиболее оптимальную версию исходя из собственных требований.
В этой модели пользовательский BfF является посредником между серверными сервисами и клиентом:

Эту модель можно реализовать в GraphQL, разместив все BfF на одном GraphQL-сервере с несколькими эндпоинтами, где каждый эндпоинт обслуживает конкретный BfF/клиент (например, /graphql/mobile и /graphql/web):
