Почему я борюсь с GraphQL

И мой взгляд на то, где это имеет смысл

Сначала несколько определений. Сам «GraphQL» буквально означает «язык запросов графов». Сама по себе система не осязаема. Он определяет метод разговора (язык) для запроса определенных данных (запрос) из сети узлов данных, которые связаны друг с другом (запрос) .

Реализация этого языка не имеет значения.

Аналогия здесь похожа на высказывание; независимо от вашей национальности, вы можете выучить английский. Это нисколько не меняет английского языка, на котором вы начали говорить, и нисколько не меняет язык, на котором вы используете ее для общения.

Однако есть способы начать работать с GraphQL, которые имеют большой смысл. Предварительно упакованные, легко начать. Один из них - Apollo, работающий на узле. Но вы можете свободно реализовать свои собственные, если хотите.

Реальное решение для DDD

Когда вы увеличили масштаб своей организации и закон Конвея послужил вам правильным решением, ваши системы начали фрагментироваться. Естественный способ фрагментировать ваше цифровое решение с помощью современных технологий - разделить его на сервисы.

Domain Driven Design (DDD) помогает определить, что должно быть в этих сервисах. Вы можете произвольно разделить функциональность по сервисам, но в идеале вы хотели бы разбить функциональность на логические кластеры. Когда вы группируете логику по бизнес-доменам, жизнь становится намного проще, потому что ответственность за них и то, что является их содержанием, может быть намного проще разделить с заинтересованными сторонами вашего бизнеса.

Но за этот, казалось бы, сверхлогичный способ работы приходится платить. Вы перейдете от КИСЛОТЫ к ОСНОВАНИЮ (нет недостатка в научных акронимах вокруг теоремы CAP). Если раньше управление состоянием осуществлялось в единой базе данных, то логика, а также состояние теперь разбросаны по всему ландшафту, по нескольким службам. Вам понадобится способ легко объединить эти данные. GraphQL приходит на помощь.

Комплекс героя

Вы когда-нибудь слышали о комплексе героя? Устранение проблем - это хорошо. Это заставляет вас чувствовать себя важным. Но если вы исправите это навсегда и структурно, есть риск, что вы больше не сможете быть героем. Вы уверены, что находитесь здесь сейчас, потому что знаете эту область. Но нельзя быть уверенным, что вы станете героем следующей проблемы, и это пугает и заставляет чувствовать себя неуместным. Пожарный разводит костры. Это случается чаще, чем вы думаете.

Я говорю вам это, потому что GraphQL действительно склонен быть героем в ситуациях, когда этого не должно быть. Он имеет тенденцию смягчать пожары там, где их действительно нужно потушить.

Прежде чем вы это узнаете, он решает всевозможные проблемы ландшафта, стоящего за ним. Нравится авторизация, Управление кешем, преобразование, комбинирование, агрегирование. Это так легко сделать там, потому что это одно место, где можно исправить все стоящие за ним системы. Боль от каждого домена переходит в эту центральную шину, и теперь нам нужно наложить пластырь на одном месте, что кажется быстрее и проще. Ежу понятно, правда? Верно…

Но давайте просто клянемся, что не будем делать всего этого. Мы не реализуем все это добро в этом сладком месте. Жизнь хороша, не правда ли?

Это настоящая борьба

Так что, с одной стороны, я обожаю тот факт, что вы можете запрашивать ландшафт своих сервисов, как если бы это была одна база данных. Он устраняет утомительную реализацию выборки данных из нескольких служб во всех местах вашего решения, потребляющих данные.

С другой стороны, это станет следующим узким местом в вашем ландшафте. Прежде чем вы это узнаете, ответственность, принадлежащая их уважаемым областям, перемещается в эту центральную точку. С каждым добавлением службы в конце потребляющие стороны должны будут ждать, пока она не будет добавлена ​​в центральную службу запросов.

Это убивает ответственность и создает единую точку отказа, где ее не должно быть. Если, конечно, это не автоматизировано и не организовано без вмешательства человека. Хотя я еще не видел такого решения. Объединение данных редко проходит без вмешательства, особенно когда на нем так много внимания.

Прогрессивное новое понимание структур данных, способов комбинирования данных и того, какую версию конечной точки следует использовать, усугубляет трудности, связанные с извлечением всех данных через эту точку доступа. Теперь вы должны учитывать все стороны-потребители, когда вам нужно изменить эту логику. Просто не имеет смысла размещать его в центре вашего ландшафта.

Ладно, хватит уже!

Если есть что-то, что мне не нравится, так это негативное мышление. Вы просто не можете сказать, что что-то не так, если у вас нет решения, как сделать это лучше, и не внести свой вклад в решение.

В случае, если у вас есть ситуация, которую я описал выше: не беспокойтесь! Он привел вас туда, где вы находитесь сегодня, но я надеюсь, что он принесет некоторое понимание того, почему важно улучшать с этого момента.

Никогда не обижайтесь на то, что у вас есть сегодня, поскольку оно привело вас к этому с самого начала. Просто внимательно проанализируйте это и не соглашайтесь на посредственность. Он покажет вам, куда вам нужно идти, чтобы стать лучше.

Ура, я только что процитировал себя прямо здесь: D

Так где это подходит?

Я думаю, что конечные точки служб с поддержкой GraphQL предлагают отличный способ для внешних партнеров запрашивать ваш ландшафт без необходимости знать все сложные детали. Затем вы можете создать версию этой конечной точки, как и все другие конечные точки, и тщательно опубликовать документацию. Вам не придется менять его так часто, и команды, отвечающие за общедоступные API, могут здесь управлять подключением и реализацией. Темпы невысоки, и эта команда не будет блокировать никакую разработку между серверными сервисами, а также фронтенд-разработку / использование этих сервисов.

А что там, где не влезет?

Я бы предоставил библиотеку, которую могла бы использовать вся внешняя разработка. Эта библиотека будет состоять из множества отдельных компонентов, управляемых в собственном репозитории командой, которая также отвечает за серверную часть. Ваши CI / CD и тестовые среды должны отключаться всякий раз, когда происходит регрессия или возникает несовместимость, как это должно происходить при всех изменениях зависимостей.

Таким образом, интерфейс может вызывать функции, которые 1–1 предоставляют интерфейс для службы, или вспомогательные функции, которые объединяют данные из нескольких служб прямо в коде. Право собственности на объединяющие функции находится в самом большом домене (иерархически самом высоком объекте). Поскольку более высокая сущность требует меньшей сущности, и наоборот, не всегда.

Этот уровень должен заботиться об обработке запросов параллельно и в правильном порядке.

Но… Именно это и делают для вас решения GraphQL.

Я знаю я знаю. И это здорово! До тех пор, пока вы не делаете это с той же службой, что и со всеми другими запросами, и человек, который работает на интерфейсе, не зависит от человека, который объединяет вещи, чтобы общаться с сервисом, созданным другим человеком. в бэкенде это хорошо!

Там, где реализация выполнена - и только на этом месте - вы должны иметь возможность адаптировать и отклоняться от фиксированных способов объединения данных по усмотрению разработчика / приложения. И при этом оставайтесь самой чистой формой прозрачности того, какую бэкэнд-логику вы фактически используете для этого.

Я знаю, что освещаю неоднозначную тему. И, как я уже писал, я тоже борюсь с этим. Контекст также является ключевым моментом. Очевидно, что размер проекта и сложность ландшафта услуг имеют значение, и я не учел этот контекст при написании этой статьи. Но я чувствую, что есть о чем поговорить. Возможно, у вас есть какие-то ценные идеи, которые заставят меня думать иначе :-). Я хотел бы услышать о них!