Напишите нам прямо сейчас, наши специалисты расскажут об услугах и ответят на все Ваши вопросы.
Напишите нам прямо сейчас, наши специалисты расскажут об услугах и ответят на все Ваши вопросы.
Наш специалист свяжется с Вами, обсудит оптимальную стратегию сотрудничества, поможет сформировать бизнес требования и рассчитает стоимость услуг.
Наш специалист свяжется с Вами, обсудит оптимальную стратегию сотрудничества, поможет сформировать бизнес требования и рассчитает стоимость услуг.
Заполните онлайн-заявку и получите выгодное спецпредложение прямо сейчас.
За вами будет закреплен персональный менеджер, который расскажет о платформе, ответит на все ваши вопросы и сформирует для вас коммерческое предложение.
Наш специалист свяжется с Вами и
обсудит время собеседования.
Разницы между GraphQL и REST в данном случае нету, подход и там и там применим.
Сами разработчики GraphQL как раз не поддерживают идею api versioning и смотрят в сторону mutable схемы в общем случае.
Как Вы в своих реальных рабочих проектах с этим справляетесь?
Потому что «нотация» GraphQL создана из рассчета, что у нас волшебный сервер, который одинаково эффективно возвращает запрошенные данные. И пофиг как там GraphQL ложится на внутреннюю предметную область, аппаратные ограничения, уже реализованные способы доступа к объектам. За исключением простых случаев, ситуация когда фронтендщики диктуют схему доступа к данным, пусть и прекрываясь технологией, черевата проблемами с производительностью и неоптимальной организацией хранения данных. Потому что для фронтендщика не будут видны под капотом ключи MySQL, лимиты на внешние апи, внутренная организация кэширования. И REST, на мой взгляд, куда лучше справляется как с учетом этих особенностей, так и защитой фронтеднщиков от этих ненужных деталей.
К тому же олновесная реализация нотации GraphQL для всех сущностей системы может стоить дорого. А реализация ограниченного подмножества будет по сути не особо отличаться от REST. Только вместо ендпоинтов для сущностей нужно будет создавать ресолверы для новых сущностей.
А вот возможность получить на сервер запрос всех полей и связанных с ними записей думаю сильно плохо скажется на его здоровье. Интересно посмотреть статистику отказа в обслуживании таких endpoint’ов.
Если пытаться на ендпоинте сделать логику выборки из базы как в авторезолверах, строящих запросы по аннотациям в ORM, то все может быть очень печально. А если сделать выборку вручную написанными запросами, созданными специально под конкретный флоу, то все может быть в разы лучше чем у GraphQL.
В REST вы тоже можете собирать с многих сервисов. Некоторые даже делают это в API gateway.
А вот возможность получить на сервер запрос всех полей и связанных с ними записей думаю сильно плохо скажется на его здоровье. Интересно посмотреть статистику отказа в обслуживании таких endpoint’ов.
А в чем плюс? Только возня с ее описанием. В случае простых рест запросов можно вообще забить на нотации и трафик и слать объекты целиком, с посылом — все что есть в ответе есть и в объекте. В случае сложных запросов десять раз подумаешь, а не проще ли было сделать конкретный ендпоинт для этого запроса, который бы слал конкретные объекты предстваления, не завязанные на схему, а нужные только для представления.
Возможность указания только тех полей, что нужно
В REST это тоже делалось задолго до создания GraphQL. Параметр fields в конце URL.
Можно за один запрос получить данные с разных backend-ов
Обожаю этот аргумент! Вы когда-нибудь писали кастомный резолвер, который вам соберет сложный объект по нескольким микросервисам? Это одинаковая головная боль, что для REST, что для GraphQL. Только в случае последнего вам придется писать резольвер по-настоящему общего назначения, который будет работать для всех полей и связанных объектов, и потом решать проблемы производительности с этим чудом. В случае REST такие вещи хотя бы ограничивают универсальность применения одним ендпоинтом и доступными для него спидхаками и упрощениями выборки.
Можно получать связанные данные (пользователь + его заказы, например)
Да можно, вопрос какой ценой нагрузки на сервер. Вероятно, можно написать хаки для ресольвера, чтобы он какие-то случаи запросов покрывал джойнами, а не выборкой связанных данных отдельными подзапросами. Но чем такие оптимизации принципиально отличаются от создания специализированного рестового ендпоинта?
Запросы к бекендам могут параллелиться без изменения логики в клиенте
Чтобы что?
— Единая нотация
— Возможность указания только тех полей, что нужно
— Можно за один запрос получить данные с разных backend-ов
— Можно получать связанные данные (пользователь + его заказы, например)
— Запросы к бекендам могут параллелиться без изменения логики в клиенте
Но есть и минусы:
— Секурити, точнее отсутствие
— Своя нотация запросов
— Нельзя указать * для полей — обязательно перечислять
— Скорость ниже, чем прямой вызов (но может быть быстрее за счёт параллелизма)
Вообще для UI подход GraphQL оказался очень удобным даже не смотря на минусы.
Сдается мне, это придумали фронтедщики, чтоб не пинать бэкендщиков по каждому чиху.
Вот только мне кажется при такой свободе и отсутствии кеширования такие запросы, особенно сложные, сильно просаживают быстродействие.
Итак, REST API применяют, если:
— работают с небольшими программами, где нужно обрабатывать простые данные
— пользователи работают с ними одинаково
— нет требований к сложным запросам
GraphQL выбирают, когда:
— у серверного оборудования маленькая пропускная способность. Необходимо снизить количество ввода-вывода данных
— в одном адресе нужно объединить множество источников
— запросы пользователей различны, необходимо прорабатывать разные ответы
Итак, REST API применяют, если:
— работают с небольшими программами, где нужно обрабатывать простые данные
— пользователи работают с ними одинаково
— нет требований к сложным запросам
GraphQL выбирают, когда:
— у серверного оборудования маленькая пропускная способность. Необходимо снизить количество ввода-вывода данных
— в одном адресе нужно объединить множество источников
— запросы пользователей различны, необходимо прорабатывать разные ответы
Итак, REST API применяют, если:
— работают с небольшими программами, где нужно обрабатывать простые данные
— пользователи работают с ними одинаково
— нет требований к сложным запросам
GraphQL выбирают, когда:
— у серверного оборудования маленькая пропускная способность. Необходимо снизить количество ввода-вывода данных
— в одном адресе нужно объединить множество источников
— запросы пользователей различны, необходимо прорабатывать разные ответы
Например, вы хотите посмотреть варианты пиццы и указываете точку /pizza. API принесёт информацию о цене, акциях и составе продукта. Но вы просили информацию о видах пиццы. Придётся постоянно прописывать конкретные адреса, а это энергозатратно для разработчиков и проблематично для пользователей.
То есть возникают проблемы с выборкой: она либо избыточна, либо недостаточна. REST не может предоставлять точные данные по запросу клиентов, потому что использует один endpoint для одного адреса.
Архитектурный стиль GraphQL позволяет сделать запросы за один раз. Клиент передаёт названия трёх мест, запрашивает нужные данные и ждёт. GraphQL выполнит все запросы и принесёт данные из разных адресов.
GraphQL: стандарт и его особенности
GraphQL — язык запросов для управления данными графов. Он использует разные виды протоколов для передачи информации. GraphQL в основном возвращает ответы в JSON.
Главное отличие GraphQL от REST API в том, что все данные клиент может выбрать всего одним запросом, даже если они будут располагаться в разных источниках. А в REST API придётся сделать выборку и извлекать их уже оттуда.
Разработчики считают GraphQL умным агрегатором, который играет роль оркестратора. Он переадресовывает фрагменты запроса на разные эндпоинты. GraphQL умеет отправлять данные поверх HTTP-протокола, Websocket и SSH. Это удобно, когда вы разрабатываете многофункциональное приложение.
GraphQL имеет три главных блока:
— Queries — запросы
— Schema — схема. Описание типов объектов и полей, принадлежащих каждому объекту
— Resolvers — функция, отвечающая за заполнение информацией полей в схеме. Способ выполнения процедуры определяет разработчик. Например, резолвер может извлекать данные из сервера или стороннего API
Для работы с графовым языком запросов есть утилита GraphiQL. Разработчик интегрирует её с Endpoint GraphQL. Он отправляет запрос серверу на предоставление своей схемы — вы получаете интерфейс для проведения тестов и изучения запросов.
Если с формированием запросов всё понятно, давайте посмотрим основные блоки кода для схем:
— Character — вид среды GraphQL
— Fields (например, name и address) — поля, заполняемые в виде объекта Character. Их находят в ответе на запрос. Каждое поле возвращает то значение, которое обрабатывает
Разберём поля подробно, потому что они составляют значительную часть возвращаемой информации. Итак, они могут быть скалярного вида, объектом, типом ввода, перечисления, объединения и интерфейсом.
Например, скалярные виды — это:
— String — определённые символы в коде UTF-8
— Int — 32-битное целое число
— Float — цифра с плавающим разделительным знаком
— Boolean — логическая информация: true или false
— ID — уникальный идентификатор. Нужен для повторной выборки объекта
GraphQL умеет анализировать синтаксис и проверять формы собственной схемой. Этот API может показаться сложным на стадии создания приложения, но подобное разделение на отдельные элементы — интересная возможность для анализа синтаксиса — позволяет получать чёткие ответы на запросы без дополнительных выборок, в отличие от REST API.
Например, вы хотите посмотреть варианты пиццы и указываете точку /pizza. API принесёт информацию о цене, акциях и составе продукта. Но вы просили информацию о видах пиццы. Придётся постоянно прописывать конкретные адреса, а это энергозатратно для разработчиков и проблематично для пользователей.
То есть возникают проблемы с выборкой: она либо избыточна, либо недостаточна. REST не может предоставлять точные данные по запросу клиентов, потому что использует один endpoint для одного адреса.
Архитектурный стиль GraphQL позволяет сделать запросы за один раз. Клиент передаёт названия трёх мест, запрашивает нужные данные и ждёт. GraphQL выполнит все запросы и принесёт данные из разных адресов.
GraphQL: стандарт и его особенности
GraphQL — язык запросов для управления данными графов. Он использует разные виды протоколов для передачи информации. GraphQL в основном возвращает ответы в JSON.
Главное отличие GraphQL от REST API в том, что все данные клиент может выбрать всего одним запросом, даже если они будут располагаться в разных источниках. А в REST API придётся сделать выборку и извлекать их уже оттуда.
Разработчики считают GraphQL умным агрегатором, который играет роль оркестратора. Он переадресовывает фрагменты запроса на разные эндпоинты. GraphQL умеет отправлять данные поверх HTTP-протокола, Websocket и SSH. Это удобно, когда вы разрабатываете многофункциональное приложение.
GraphQL имеет три главных блока:
— Queries — запросы
— Schema — схема. Описание типов объектов и полей, принадлежащих каждому объекту
— Resolvers — функция, отвечающая за заполнение информацией полей в схеме. Способ выполнения процедуры определяет разработчик. Например, резолвер может извлекать данные из сервера или стороннего API
Для работы с графовым языком запросов есть утилита GraphiQL. Разработчик интегрирует её с Endpoint GraphQL. Он отправляет запрос серверу на предоставление своей схемы — вы получаете интерфейс для проведения тестов и изучения запросов.
Если с формированием запросов всё понятно, давайте посмотрим основные блоки кода для схем:
— Character — вид среды GraphQL
— Fields (например, name и address) — поля, заполняемые в виде объекта Character. Их находят в ответе на запрос. Каждое поле возвращает то значение, которое обрабатывает
Разберём поля подробно, потому что они составляют значительную часть возвращаемой информации. Итак, они могут быть скалярного вида, объектом, типом ввода, перечисления, объединения и интерфейсом.
Например, скалярные виды — это:
— String — определённые символы в коде UTF-8
— Int — 32-битное целое число
— Float — цифра с плавающим разделительным знаком
— Boolean — логическая информация: true или false
— ID — уникальный идентификатор. Нужен для повторной выборки объекта
GraphQL умеет анализировать синтаксис и проверять формы собственной схемой. Этот API может показаться сложным на стадии создания приложения, но подобное разделение на отдельные элементы — интересная возможность для анализа синтаксиса — позволяет получать чёткие ответы на запросы без дополнительных выборок, в отличие от REST API.
Например, вы хотите посмотреть варианты пиццы и указываете точку /pizza. API принесёт информацию о цене, акциях и составе продукта. Но вы просили информацию о видах пиццы. Придётся постоянно прописывать конкретные адреса, а это энергозатратно для разработчиков и проблематично для пользователей.
То есть возникают проблемы с выборкой: она либо избыточна, либо недостаточна. REST не может предоставлять точные данные по запросу клиентов, потому что использует один endpoint для одного адреса.
Архитектурный стиль GraphQL позволяет сделать запросы за один раз. Клиент передаёт названия трёх мест, запрашивает нужные данные и ждёт. GraphQL выполнит все запросы и принесёт данные из разных адресов.
GraphQL: стандарт и его особенности
GraphQL — язык запросов для управления данными графов. Он использует разные виды протоколов для передачи информации. GraphQL в основном возвращает ответы в JSON.
Главное отличие GraphQL от REST API в том, что все данные клиент может выбрать всего одним запросом, даже если они будут располагаться в разных источниках. А в REST API придётся сделать выборку и извлекать их уже оттуда.
Разработчики считают GraphQL умным агрегатором, который играет роль оркестратора. Он переадресовывает фрагменты запроса на разные эндпоинты. GraphQL умеет отправлять данные поверх HTTP-протокола, Websocket и SSH. Это удобно, когда вы разрабатываете многофункциональное приложение.
GraphQL имеет три главных блока:
— Queries — запросы
— Schema — схема. Описание типов объектов и полей, принадлежащих каждому объекту
— Resolvers — функция, отвечающая за заполнение информацией полей в схеме. Способ выполнения процедуры определяет разработчик. Например, резолвер может извлекать данные из сервера или стороннего API
Для работы с графовым языком запросов есть утилита GraphiQL. Разработчик интегрирует её с Endpoint GraphQL. Он отправляет запрос серверу на предоставление своей схемы — вы получаете интерфейс для проведения тестов и изучения запросов.
Если с формированием запросов всё понятно, давайте посмотрим основные блоки кода для схем:
— Character — вид среды GraphQL
— Fields (например, name и address) — поля, заполняемые в виде объекта Character. Их находят в ответе на запрос. Каждое поле возвращает то значение, которое обрабатывает
Разберём поля подробно, потому что они составляют значительную часть возвращаемой информации. Итак, они могут быть скалярного вида, объектом, типом ввода, перечисления, объединения и интерфейсом.
Например, скалярные виды — это:
— String — определённые символы в коде UTF-8
— Int — 32-битное целое число
— Float — цифра с плавающим разделительным знаком
— Boolean — логическая информация: true или false
— ID — уникальный идентификатор. Нужен для повторной выборки объекта
GraphQL умеет анализировать синтаксис и проверять формы собственной схемой. Этот API может показаться сложным на стадии создания приложения, но подобное разделение на отдельные элементы — интересная возможность для анализа синтаксиса — позволяет получать чёткие ответы на запросы без дополнительных выборок, в отличие от REST API.
Сложно угадать что вы имели введу, но возможно то, что математик пытался бежать впереди поровоза в духе «я знаю что это потом понадобиться». Не, это неправильно, это зло.
Но, если у нас предметная область различается хоть на 1 поле, тогда:
Сущность user уже с первых строк кода могла быть реализовнана как целая домення область из user-core, user-address, credentials, user audit, connected apps, payment data
Это правильно. Хороший контекст и домен превыше всего. Вообще всего. Потому что это залог:
1. минимизации ошибок в реализации
2. минимизации скрытых ошибок и сайд-эффектов
3. возможности передать код след. разработчику, и позволить ему разобраться в нём так, что тот выполнит п.1. и 2.
Можно жить с низкой производительностью — её можно улучшить. Можно жить с техническими багами реализации или недоделками (ну типа нет 100500 валидации на такое-то условие) — их можно исправить. Нельзя существовать с продуктом, которые делает не то, что нужно, да ещё и скрыто. И при этом не позволяет себя исправить ( например исправление только за счёт костылей, что вносит сумятицу и сайд-эффекты. разраб уволился, с ним и знание «а почему так», а код и контекст не говорят почему)
Но конечно, заготовки делать на случай просматривающегося контекста — это тоже зло. Разработка и развитие предметной области сродне лепки из пластилина или глины (обратное резьбе по камню): меся обрастает, потом переосмысление, рефакторинг всего. Если есть опыт, то рефакторинг проходит легко. Если говнокодили в начале, то с болью. Но нужно развивать доменную область, которая отображает фактическую модель систему — а не:
а) изначально запланированную, но которая оказалось избыточной\недоделанной
б) изначально незапланированную, но вылепленную без «развития», а потому таскающую за собой кучу легаси свойств и зависимостей из других контекстов, которые поленились создать\не поняли что надо создать.
почемуто раз в 5 больше ненужных усложнений в виде сущностей.
Слава Богу его можно было убедить словами и рефакторинг он не воспринимал болезненно.
Ну это и есть то самое развитие. Насоздавал. Понял что 5 из 8 сущностей лишние или дубли — удалил. Это норма.
Если рефакторинг перед началом каждой новой задачи, во время изменения куска кода или фикса бага то и нет проблем с поступательным развитием. А если рефакторинг — это плановая задача «вернуть тех. долг», то всё, считай нет и не будет его никогда.
не совсем так думаю про:
Не создавайте ненужных сущностей без необходимости.
мне всегда казалось это о другом
Например я работал как-то в одной команде с отличным матиматиком (притворяющимся программистом ;) очень не плохо в целом) который каждую маломальскую сущнусь стремился усложнить по максимому.
Сущность user уже с первых строк кода могла быть реализовнана как целая домення область из user-core, user-address, credentials, user audit, connected apps, payment data
и так со всеми остальными, тоесть в среденм в его коде по сравнению со всеми остальными было почемуто раз в 5 больше ненужных усложнений в виде сущностей.
Слава Богу его можно было убедить словами и рефакторинг он не воспринимал болезненно. Но я всегда впоминал именно этот принцип и его ужасное нарушение. Может я конечно что-то не так понял. ;)
Вот это лютый бред и трешак, который привёл к монолитизации и колоссальному увеличению связанности и мешает людям подняться на ступень выше в написании качественного кода. С ним возятся до сих пор, хотя больше плохого, чем хорошего. Ну при условии что вы не мамкин сайт домашний пишите, а приложение миллионов на 5-7 строк кода. Он актуален исключительно в среде теоретиков и джунов, чтобы последние не копипастили один и тот же код в разных классах.
На практике, люди, упоротые этим принципом и не знающие других подходов с огромной болью живут в огромном монолитие с единой dll типа DAL единой dll типа DomainModel и т.д.
Всё это таскается из одного проекта в другой, шарится между десятками сервисов и апи и потом распилить такое на микро сервисы просто невозможно, точнее бизнес не хочет. Цена поддержки растёт кратно. Зато без копирования, ага.
Как нужно делать:
1. Не копировать код в рамках 1 класса и одной, при возможности одной dll.
2. Делать всё в рамках одной фичи. А ля микросервис. Это означает что нет никаких папок с кучей разных репозиотриев а ля Reposotories/AccountRepository и тут же Reposotories/OrdersRepository. А есть 2 фичи (Accounts/ Orders/) внутри которых есть такие репо (Accounts/AccountRepo, Accounts/AccountFactory, Orders/OrderRepo...). В будущем это позволит разделить контексты И если вдруг фиче про ордера нужен доступ к данным из аккаунта, то да, копипастится логика хоть полностью и делается свой репо (Orders/AcountForOrdersRepo… ). Менять её придётся разве что раз в 1000 лет. А вот поддерживать и менять в рамках одной фичи — сколько угодно раз. И нафига тогда нужен такая связанность с Account фичей? Нет уж.
3. По мере разрастания кода — разносить вообще в разные библиотеки (контексты) и репозитории.
А DRY на помойку.
Прежде чем переходить к реализации, убедитесь, что все хорошо продумано.
Это тоже теоретическая чушь, которая на практике сводится к:
1) мы уже делали такое и знаем что примерно нужно сделать ещё раз. Тогда проблемы нет.
2) мы ещё не делали такое и хз что нас ждёт. В этом случае ничего не поможет, ничего не угадать. Например мы на своём проекте несколько лет использовали singlar для для работы множества клиентов с сервером и сервер с очередью через RebbitMQ. В итоге отказались от подхода, как нестабильного, перешли на realtime запрос-ответ. Угадать заранее, фактически без прототипа в продакшене такое было невозможно.
Что же на самом деле лучше сделать в таком случае?
а) Изучить максимум инфы по данной технологии.
б) делать простые небольшие изолированные куски. Потом с увеличением их числа вовремя рефакторить и объединять в контексты. Постоянный рефакторинг — только он поможет избежать факапа. А рефакторинг подразумевает поднятие на уровень выше в архитектуре и её пересмотр в том числе. Когда время пришло.
SOLID
Вот это must have и за его нарушение (чаще всего S) увольнять к чертям. Оно хоть как-то спасает от связанности и роста проблем.
Не создавайте ненужных сущностей без необходимости.
Очередной теоретический бред для джунов, наверное. Сущности всегда создаются в зависимости от контекста и бизнеса. Если у тебя 5 вариантов работы с ордерами и в одном случае нужны одни поля, а в другом — другие и только id + name общие, то это разные сущности. И их нужно создавать. А не гонять одну God object по всему домену. Увеличивая связанность. Если тебе нужно вернуть объект в виде json то не нужно возвращать сущность из предметной области. Пусть она хоть 1 в 1 пока совпадает с DTO объектом. Ключевое слово тут «пока» совпадает.
Фаулер и Макконели верно говорят, что самое дорогое — поддержка. А поддержка дорожает с увеличением сложности. А сложность в том числе берётся и от связанность, из-за невозможности просто удалить и заново переписать кусок. А вдруг кому-то что-то сломает?!
Солид противоречит ягни, драй и кису. То есть конечно, иногда они успешно сосуществуют в некоторых местах. Но есть достаточно слуачев когда надо выбирать. И я агитирую за выбор солида.