.Net Developer
  • Конвертуємо наявний REST API в GraphQL API

    Перевів на dapper і змінив підхід до генерації в окремому бранчі. Я б сказав стало більш прямолінійно.

    github.com/...​ee/feature/move-to-dapper

    Підтримав: Volodymyr Verdysh
  • Конвертуємо наявний REST API в GraphQL API

    Зробив повноціний приклад github.com/...​/GraphQLSQLProcessExample
    Почати дивитися можна з ExtensionService.GetExtensions.

    1. Виглядає як Count на рівні процеса. Але нащо він нам в DataLoader-і для extensions?

    Так, то я тупонув. В цьому прикладі використовується правильний count. Він буде рахувати саме extensions

    2. Можна детальніше куди саме глянути і як саме вирубити?

    Все показано в ExtensionService, а саме в GetCountSql та GetExtensionsSql.

    3. Як в DataLoader-і отримати встановлене клієнтом сортування для extentions?

    В моєму прикладі це є. Тільки зараз зрозумів що реалізував не зовсім те що тут в прикладі. У мене сортування на рівні extentions. Тут сортування на рівні processes by extensions. Щоб зробити як тут треба розширити ProcessService і генерити кастомний ORDER BY на базі ProcessOrderByField. Зараз там все дуже примітивно зроблено, але розширити повинно бути дуже просто. Думаю займусь цим трохи пізніше.

    Підтримав: Volodymyr Verdysh
  • У Dell працівникам поставили умову: або ремоут, або підвищення. Обговорюємо

    > Гаїті — одна з найбідніших країн світу і найвідсталіша в Центральній та Південній Америці. Рівень безробіття — 60 %, письменності — 54,8 %,

  • Конвертуємо наявний REST API в GraphQL API

    Я б зробив якось так:
    ``` graphql
    type Query {
    processes: [Process]
    }

    type Process {
    id: Int!
    name: String!
    extenstions: ExtentionsQueryNode
    }

    type ExtentionsQueryNode {
    count: Int!
    extentions: [Extention]!
    }

    type Extention {
    extension: String!
    count: Int!
    }
    ```

    `` extenstions: ExtentionsQueryNode `` - це окремий резолвер який працює саме з extention-ами, приймає `` Process `` як parent, передає його ід в лоадер. Далі на рівні sql-я буде запит в наступному стилі:
    ``` sql
    select count(*) as Count,
    (select extention, count(*) as Count from Extentions where ProcessId = @ProcessId groupBy extention FOR JSON PATH) as JSON
    from Extentions
    where ProcessId = @ProcessId
    ```
    З такою реалізацією ми зрівняємося з REST. Додатково можна глянути що саме юзер вибрав із `` ExtentionsQueryNode `` і вирубати частину sql квері якщо вона не потрібна. Так наприклад, якщо треба тільки count, то не робити inner select і навпаки. Ну і сортування тут можна запроста запихнути в inner select

  • Обговорення рейтингу мов програмування 2024

    Ну докер точно домінує в категорії продукти Hashicorp =) Але це не можна назвати нішою)

    Докер, кубернетес, memgraph та cockroachd

    Круто! Тільки тут питання яка вірогідність розорбника з доу попасти на такі проекти? Я думаю набагато менше 2%. А тим більш джуну який шукає роботу

  • Обговорення рейтингу мов програмування 2024

    Я б не сказав що 2% із 92%(сумма % мов що вище за нього по рейтингу), щось говорить про його популярність окрім як що є набір фанатів що намагаються просувати його скрізь. Єдина ніша де він якось застосовується це різні web api. В цьому випадку вірогідність бути сповільними мовою програмування дуже зменшується, оскільки 95% швидкодії залежиться від DB та архітектури що захована за цим API. Тут он на PHP фейсбук живе і норм. Так PHP там покращений, але до C#/JAVA йому далеко.

  • Обговорення рейтингу мов програмування 2024

    вiн не конкурент згаданим високорiвневим мовам в ентепрайзi

    А кому тоді він конкурент?

  • Конвертуємо наявний REST API в GraphQL API

    ми завжди виберемо з бази ід і ім’я

    Це можна оптимізувати. В HotChocolate є всі необхідні штуки для цього. Просто не хотілось ускладнювати реалізаацію.

    ми хочемо для поточного користувача отримати не всі ролі

    Нічого не заважає добавити фільтри в GraphQL філд. В результаті, матимемо такий extension

    Task<Role[]> GetRoles([Parent] User user, int page, int size, string filter, [Service] RoleService roleService)
    

    Ну і сама кверя

    query GetUsers($userId: Int!, $page: Int!, $size: Int!, $filter: String!) {
      user(id: $userId) {
        id
        email
        roles(page: $page, size: $size, filter: $filter) {
          id
        }
      }
    }
    
    складність його розробки

    В чому саме складність розробки? По факту ті ж самі контролери з іншими атрибутами.

    складність його підтримки на великих проектах

    Мені здається навпаки. Якщо ми маємо великий REST проект то практично завжди одна й та ж сутністі буде використовуватися в різних місцях по різному. В результаті, будуть додаткові ендпоїнти чи сервіси які роблять одне й теж, але трохи по різному. Відслідковувати це у великому проекті ще та проблема. З GraphQL є нас буде одна реалізація яку можна приатачити в потрібне місце.

  • Конвертуємо наявний REST API в GraphQL API

    якщо писати в декілька сутностей?

    Мається на увазі декілька GraphQL філдів? Кожен з них буде запускати в своєму скоупі, тому транзакції між ними не вийде. Якщо потрібна транзакційність, то це прямо конкретний тісно повязаний use case і його варто обєднати під одну мутацію(один GraphQL філд). Далі уже як звичайно.

  • Конвертуємо наявний REST API в GraphQL API

    Необхідність у процесі розробки використовувати додаткові тули

    Це залежить від того наскільки великий проект і від того які тулзи на ньому використовуються. Так якщо на проекті уже використовується OpenAPI та кодогенерація клієнтів до нього, то сетап GraphQL-я не буде суттєво відрізнятися. У вас буде веб «IDE» де можна визивати ендпоїнти, будуть типізовані клієнти для інтеграційних тестів та фронта. З точко зору розробника той самий флоу, тільки інший набір тузів.

    Якщо у вас немає всього цього для REST-у, то так — дуже багато нового.

    а навіщо це все?

    Я не говорю що це потрібно всім. Мета була показати як відносно просто можна конвертувати REST API в GraphQL API.

    Якщо мої задачі радикально відрізняються від цього всього, то й використовувати слід щось інше.

    Якщо у вас декілька продуктів чи декілька реалізацій одного ж і того продукту на багатьох платформах, то GraphQL може дуже корисним. Якщо ж у вас один API і одна реалізація продукту що його використовує, то напевно він вам не потрібен.

  • Конвертуємо наявний REST API в GraphQL API

    Один виклик на бек в REST буде тільки якщо створити ендпоїнт спеціально для цього юзкейсу. Юзкейсів для тих самих даних багато. Будуть «дублікати» які повертають одне й те саме, але трохи по іншому. Щоб цього уникнути треба буде робити декілька незалежних ендпоїнтів аби не тягнути все зразу коли воно не портібно.

    В результаті, ми попадаємо в ситуацію, що є два послідовні запити. В REST ми отримуємо першу відповідь і ідемо за додатковою інвормацією. В цьому випакду timeline буде наступний.
    При нормальному інеті:
    — починаємо перший запит
    — 20мс доставка запиту до серверу
    — 10мс обробка запиту
    — 20мс доставка відповіді назад

    — беремо ідшники і робимо другий запит
    — 20мс доставка запиту до серверу
    — 10мс обробка запиту
    — 20мс доставка відповіді назад

    Ітого: 100ms

    При мобільному інеті:
    — починаємо перший запит
    — 50-100мс доставка запиту до серверу
    — 10мс обробка запиту
    — 50-100мс доставка відповіді назад

    — беремо ідшники і робимо другий запит
    — 50-100мс доставка запиту до серверу
    — 10мс обробка запиту
    — 50-100мс доставка відповіді назад

    Ітого: 220ms — 420ms

    З GraphQL
    При нормальному інеті:
    — починаємо перший запит
    — 20мс доставка запиту до серверу
    — 10мс обробка запиту
    — беремо ідшники і робимо другий запит
    — 10мс обробка запиту
    — 20мс доставка відповіді назад

    Ітого: 60ms — 40% покращення

    При мобільному інеті:
    — починаємо запит
    — 50-100мс доставка запиту до серверу
    — 10мс обробка запиту
    — беремо ідшники і робимо другий запит
    — 10мс обробка запиту
    — 50-100мс доставка відповіді назад

    Ітого: 120ms — 220ms ~ 50% покращення

    Це при умові що сервер близько. Якщо він на сусідньому континенті, то нетворк буде x2-3. Покращення будуть ще суттєвіші. При цьому це все працює на існуючій інфрастурктурі і ніяких магічних налаштувать бази не треба.

    І не кажіть що такого не буває чи треба тільки заоптимізувати вокфлоу і все буде збс. В моїй практиці кровавого ентерпрайзу, я бачив кучу прикладів де були і 3 і більше послідовних запитів.

    Підтримав: Вадим Міхневич
  • Конвертуємо наявний REST API в GraphQL API

    Я мав справу з BFF. Як результат, api для консюмерів робили деякі речі «трохи по своєму». Це прозводило до багрепортів. Знову і знову. Це не говорячи що реалізація нової фічі вимагала реалізувати її декілька разів, а потім і протестувати декілька разів.

  • Конвертуємо наявний REST API в GraphQL API

    Ну тоді можна сказати наступне:

    Ну правильно, в цьому ж і суть що можна отримати той самий функціонал, але в парадигмі TCP, тому записувати недоліки це не можна. В TCP взагалі нема нічого про організацію фільтрів і т.д то будемо говорити що це недоліки? Різниця тільки в тому що foundation of data communication for the World Wide Web заопенсорсила свій велосипед HTTP і його підтримує щоб не було «проблем з підтримкою», а імплементації на основі TCP нема, от і все. Якби TCP накладала обмеження, що унеможливлювала б це, то це вже інша справа.

    А якщо серйозно то тут різниця в тому що з REST у вас свій власний велосипед про який ніхто крім вас не знає. GraphQL — має спеку і різні реалізації. Це дає можлвість брати його і інтергувати між собою різні продукти.

    Підтримав: Антон Касьянов
  • Конвертуємо наявний REST API в GraphQL API

    ORM(HotChocolate має інтеграції з різними провайдерами) точно спростить використання, але не обов’язково. Ми можемо дробити запити на рівні GraphQL полів враховуючи внутрішню структуру бази.

    Наприклад, у нас є юзер і його ролі. Скоріше за все вони лежать в різних таблицях. Тому було б логічно зробити два незалежних GraphQL поля. В результаті, якщо не буде запитів на ролі, то й не і буде запиту в базу.

    Додатково можна самому подивитися на філди які були запитані і згенерити на основі цього сирий SQL. Ми так робимо для великих моделей, що логічно об’єднані.

  • Конвертуємо наявний REST API в GraphQL API

    використовують всього ~20% юзерів

    Я думав що буде менше) Тут важливіше дивитися на вимоги продукту. Якщо у вас є API що працює зразу з декількома продуктами або декількома версіями одного й того ж продукту, то тут GraphQL може бути уже корисним.

    З іншої сторони мені подобається сама модель написання GraphQL полів. Коли ми описуємо сутність і як її дістати, а потім можемо приатачити цю сутніть до будь чого. Це допомагає працювати над чимось цікавим, а не прокидувані одного й того ж набору полів в десяток ендпоїнтів і різними inner join-ами всередені.

  • Конвертуємо наявний REST API в GraphQL API

    На моєму проекті є декілька місць де зроблено саме так, якраз щоб забезпечити мінімальний час відповіді. В той самий час, реалізувати та підтримувати це буде на порядки складніше. Тому зазвичай буде достатньо підходу що описано в статі. Він уже може нівелюювати суттєвий шматок часу під час початкового завантаження сторінки, оскільки мінімізує latency від запитів, що може бути 20-50мс на запит. Це чисто відправка пакету через інтернет до серверу.

  • Конвертуємо наявний REST API в GraphQL API

    Це необов’язково повинні бути зовнішні консюмери. Це може бути декілька продуктів однієї компанії або різні версії одного й того ж продукту на різних платформах(веб, мобілки).

  • Конвертуємо наявний REST API в GraphQL API

    Так в тому і проблема що вимоги до ендпоїнтів можуть бути різними. В результаті, потрібні різні ендпоїнти які повертають приблизно одні й тіж дані. GraphQL дозволяє їх обєднати і юніфікувати.

    Підтримав: Olga Zlishcheva
  • Конвертуємо наявний REST API в GraphQL API

    Напряму «сирі» запити краще не відправляти. Для цього є GraphQL клієнти з тулінгом навколо них.

    Для JS/TS apollo client — там повна підсвітка синтаксису, валідація запитів та autocomplete полів GraphQL + повна автоматична типизація відповідей через кодогенерацію.

    Для C# я б виділив Strawberry Shake, що конвертуює GraphQL файли з запитами в типізовані врапери на C#. А також мій проект ZeroQL. Він дозволяє писати запити повністю на С# з чудовою швидкодією в рантаймі, але фіч поки менше ніж в Strawberry Shake.

    Повний список для різних мов можна глянути тут graphql.org/code

  • Конвертуємо наявний REST API в GraphQL API

    фасеты же есть на такую вариативность

    Ну так вони підпадають під другий спосіб що я описав + трохи over-fetching-а. Так, наприклад, передаємо { «facets»: [«user», «roles»] } i отримуюємо { id, name, email, imageUrl, roles: [ id, name ]}. Хоча по факту нам треба тільки { id, name, roles: [ name ] }. Крім того, виникає ситуація що структура відповіді має дуже ефімерний зв’язок з параметрами що прийшли. Ми можемо забути передати один із фасетів отримати null і подумати що так і треба. В GraphQL є пряма залежність між квері та структурою у відповіді. Ми просто не зможемо взяти поле яке ми забули запросити.

    Стосовно статі,

    Introspection Attack, GraphiQL — ті самі проблеми щой в REST якщо використовувати OpenAPI.

    Excessive Errors/Fields Suggestions, Pagination Limit, SQL Injection, Cross-Site Scripting, OS Command Injection, Server-Side Request Forgery — проблеми притаманні для будь-якого API

    Batching Attacks, Alias Overloading, Field Duplication, Directives Overloading, Circular Queries, Circular Fragments — HotChocolate вруховує ці проблеми. Деякі фічі просто виключені(Batching Attacks). На інші встановлені ліміти.

    Підтримав: Петтинг Пудинга
← Сtrl 123456...10 Ctrl →