Fi1osof

Fi1osof

С нами с 05 мая 2014; Место в рейтинге пользователей: #10
Fi1osof
14 августа 2019, 19:56
0
Хотя, если бы мы обсуждали не абстрактную вещь в стиле «смотрите какая крутая штука есть. на ней можно делать то и се», а разбирали реализацию GraphQL хотя бы для modx_site_content + TV, то такой материал вызвал бы
— намного больше интереса в сообществе
— позволил бы углубиться в тонкости технологии с пользой для CMS и т.п.
Нифига бы он не вызвал. Давно замечено, что чем проще, тем шире аудитория. А тем трем, кому реально интересно и захотел бы попытаться вникнуть, я вот еще почти год назад писал: prisma-cms.com/topics/izmenennaya-versiya-modxclub.ru-na-prisma-cms-poka-chto-eshhe-v-svyazke-s-modx-2817.html
Там много материала для изучения и форвардинга запросов на MODX вместе с кукисами (для авторизации), и работа с БД напрямую (не только modx_site_content). Если кому интересно, здесь частично схема: github.com/prisma-cms/boilerplate-modx/tree/master/src/server/modules/modx/schema/api

В общем, наработки были, но развивать их не стал за отсутствием надобности.
Fi1osof
14 августа 2019, 17:59
0
P.P.S. Жизнь-боль… Здесь, на мегапрофильном MODX-проекте (потому что MODX сам по себе офигенный, а все сторонние технологии от лукавого), нет даже автосохранения черновиков для комментариев. Писал-писал, а потом оп, сохраняю, а мне 404… При чем вот такая дичь: www.youtube.com/watch?v=kVENZ3DhR08&feature=youtu.be

Хорошо хоть получилось вытащить коммент из запроса в дубле вкладки, переписывать бы поленился.
Fi1osof
14 августа 2019, 17:55
+1
Местами повторюсь, потому что большую часть описал выше.

За весь GraphQL не скажу, давно уже не работал напрямую с ним (ибо без дополнительных инструментов работать с ним тяжеловато местами). Но в призме есть возможность защитить эндпоинт, указан managementApiSecret в конфигурации docker-инстанса. www.prisma.io/docs/prisma-server/authentication-and-security-kke4/#prisma-server
В таком случае для работой по АПИ придется указывать токен доступа.

На счет данных внутри, тут хитрее задача (имеется ввиду, когда, к примеру, пользователю надо ограничить доступ к отдельным полям объектов в результатах запроса). Я пока универсального средства не нашел. Но пара моментов, которые я использую:

1. Резолверы на отдельные поля объектов.
К примеру, такая схема:
type Query {
  users: [User!]!
}

type User {
  id: ID!
  username: String!
  password: String!
  email: String!
}
Мы можем прописать отдельные резолверы для каждого поля. К примеру:
const resolvers = {

  /**
   * Получение списка пользователей
   */
  users: (source, args, ctx, info) => {

    return ctx.db.query.users(args, info);
  },

  /**
   * Резолверы для полей объекта Пользователь
   */
  User: {

    password: (source, args, ctx, info) => {

      /**
       * Пароль всегда пустой возвращаем
       */
      return null;
    },

    email: (source, args, ctx, info) => {

      const {
        id,
        email,
      } = source || {};

      const {
        id: currentUserId,
      } = ctx.currentUser || {}

      /**
       * Возвращаем емейл, только если это объект текущего пользователя
       */
      return currentUserId && id && currentUserId === id ? email : null;
    },

  },

}
Самое приятное в этом способе то, что это распространяется на любые выборки в любой части запроса/подзапроса. То есть даже если запросят Топики->Комментарии->КемСоздано(User)->{email, password}, даже в этом случае поля будут прогоняться через эти резолверы. И даже в мутациях и подписках.

Вот реальный код: github.com/prisma-cms/user-module/blob/7fc769cbf1635799442fdd798f6c2f209fa7a8c2/src/modules/index.mjs#L1203-L1295

2. Чистка лишних типов.
Пример выше годится тогда, когда права разграничиваются, а не просто исключаются (как в случае с емейлами, которые могут видеть сами пользователи, если это их емейл, и админы). Но бывают случаи, когда поля вообще надо исключить из схемы, чтобы их даже запрашивать не могли, чтобы даже не знали о их существовании. Вот тогда вообще приходится чистить схему.
К примеру, вот здесь я перечисляю те объекты, которые надо вычистить из схемы: github.com/prisma-cms/boilerplate/blob/05ace079c039c48fac5a936967a40297692001fa/src/server/modules/index.mjs#L99-L180
Сама чистка выполняется здесь.

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

Ну и самая дыра по безопасности, это мутации вложенные. К примеру для запросов
mutation {
    updateTopic (
            data: {
                user: {
                    create: {
                        id: '...',
                        ...
                        sudo: true,
                    },
                }
            }
        ){
        id
    }
}


Вот такое, в отличие от резолверов на чтение, где объявил в одном месте и везде это прогоняется, просто так не заткнешь. Поэтому я на автомате вычищаю все create/update/upsert из связанных моделей. Но все равно еще есть узкие места. Вот эта задача до сих пор для меня не полностью разрешенная. Хотя на горизонте начинают маячить варианты.

P.S. В Go не силен пока, но эти приемы должны одинаково работать на любых имплементациях.
Fi1osof
14 августа 2019, 11:21
0
github.com/VadimDez/Counter-Strike-JS
Спасибо!
Fi1osof
14 августа 2019, 11:15
-1
Фраза агрегирование нескольких API в один — это описание задачи. А forwardTo — это конкретное средство решение данной задачи.
Fi1osof
14 августа 2019, 11:06
0
Одно и то же разными словами.
Нет, в данном случае не одно и то же. Уточню.

Посмотри внимательно код по ссылке.
const {forwardTo} = require('prisma-binding')

const resolvers = {
  Query: {
    posts: forwardTo('db')
  }
}

const server = new GraphQLServer({
  typeDefs: './src/schema.graphql',
  resolvers,
  context: req => ({
    ...req,
    db: new Prisma({
      typeDefs: 'src/generated/prisma.graphql',
      endpoint: '...',
      secret: 'mysecret123',
    }),
    debug: true,
  }),
})

server.start(
  () => console.log(`Server is running on http://localhost:4000`),
)
Вот мы объявляем новый GraphQL-сервер:
db: new Prisma({
      typeDefs: 'src/generated/prisma.graphql',
      endpoint: '...',
      secret: 'mysecret123',
    }),
Это наш сервер, и схема наша, то есть полноценный сервер. Мы можем создать несколько таких отдельных серверов, каждый со своим эндпоином.

И все это мы оборачиваем в единый сервер:
const server = new GraphQLServer({
  typeDefs: './src/schema.graphql',
  resolvers,
Что это дает?
1. При желании, мы можем эндпоинты подсерверов скрыть за фаервол или типа того, то есть не давать прямого доступа к подсерверу.
2. Не дублировать в резолверах функционал этих подсерверов. В резолвере, вместо того, чтобы переписывать код, мы просто переводим запрос на подсервер.
const resolvers = {
  Query: {
    posts: forwardTo('db')
  }
}
То есть это полезно, когда делал несколько отдельных проектов, и решил их все объединить в единое АПИ, но не переписывать код.

Можно я рядом создам топик про сервера для Counter Strike?
Если будет на js, я бы почитал.
Fi1osof
14 августа 2019, 09:43
+1
Тема еще не до конца раскрыта. Еще не рассказывалось толком ничего про подписки (Subscription), но это уже отдельная тема и отдельный топик.

P.S. А еще не раскрыта возможность использования forwardTo запросов, что позволяет как бы строить сеть микросервисов. Несколько отдельных API-серверов могут взаимодействовать друг с другом. Шлешь запрос на один сервер, а тот собирает информацию с разных серверов и возвращает все в одном ответе. Но это уже не совсем ядро. а различные реализации поверх.
Fi1osof
13 августа 2019, 19:41
0
Вывел информацию о созданных мирах: prisma-cms.com/minecraft/
К мирам, в которых есть игроки в режиме CREATIVE можно подключаться (в качестве имени мира указывается выведенный ай-ди (не я это придумал, но позже наверняка исправится)), и там можно увидеть других пользователей, если кто есть. Где кто есть, можно ориентироваться по координатам из таблицы. Свои координаты можно увидеть, нажав X (отладочную информацию выводить будет).
Fi1osof
13 августа 2019, 14:35
0
Это не важно, так, мысли вслух, и очень субъективно.
Fi1osof
13 августа 2019, 14:32
0
Я видел эту статью и изучал ее, но в итоге отказался от предложенного пути. Более интересны показались примеры типа этого: react-imago3d.alessiodicrescenzo.com/
Но это было полгода назад, сейчас много новых интересных наработок появилось.
Fi1osof
13 августа 2019, 09:55
+2
Посмеялся))) Так действительно лучше. Поправил :)
Fi1osof
13 августа 2019, 09:33
0
Не за что.

a-frame хорош тем, что под него есть реакт-обертки (наверняка vue тоже). Во всяком случае я делал, работает, и даже на телефоне 3D получается. У меня вот отдельная ветка задач по нему есть: prisma-cms.com/projects/issledovaniya
Там если зеленые покликать, в них более подробное описания есть и ссылки на статьи. Например, вот эта довольно интересная: modxclub.ru/topics/a-frame.-sobytiya.html
Fi1osof
13 августа 2019, 09:29
0
Через некоторое время поймешь, как MODX не ограничен собой, и как все больше и больше приходится интегрироваться с другими технологиями.
К слову, тот же MODX состоит в том числе и из технологий, которые вообще не для него создавались (phpThumb, smarty, phpMailer, ExtJS и т.п.). По одному только ExtJS заметок сколько: modx.pro/search?query=extjs
А если почитать эти заметки, то бОльшая их часть сопровождается болью. Но «ежики плакали и кололись, но продолжали жрать кактус».

У меня было бы желание, я мог бы полностью переписать админку MODX-а, и это было бы во много раз удобней и перспективней. Вот пример более удобного управления контентом: www.youtube.com/watch?v=jeDCUtkNgL0

При этом MODX не перестал бы при этом быть MODX-ом. (Если ExtJS заменить на Vue/React или типа того, MODX же не поменяется по своей сути).
Василий наверняка мог бы переписать. Может еще пара человек. Кто-то еще? Нет, потому что знаний не хватит. При этом знаний типа хватает говорить «эти технологии MODX не касаются», вообще не понимая где что чего касается.

P.S. MODX уже 10 лет не пишется MODx.
Fi1osof
13 августа 2019, 09:16
0
Каждый раз надеюсь на лучшее, но опять все зря.

P.S. обрати внимание, я только раз сказал, что ухожу насовсем. В другие разы (как и сейчас), я говорю "Пока что не буду".
Fi1osof
13 августа 2019, 08:56
0
Т.е. высказывать свою точку зрения можно только после года регистрации? :)
Конечно можно. Но вот это заявление слишком категоричное:
modx.pro сейчас узконаправленный проект, никогда не против чего-то нового, но это новое должно либо пересекаться в modx, либо нужно менять структуру сайта, например делать новый раздел.
Как будто это твой ресурс.
Свое мнение нужно сопровождать словами «Как мне кажется… Лично для меня и т.п.», а не выносить приговор за всех. Как мне кажется.

хоть блог тут свой заводи
Вот жешь незадача, здесь нельзя завести свой блог…
Fi1osof
13 августа 2019, 08:40
0
iWatchYouFromAfar
С нами с 29 сентября 2018;
Может хоть до годика дотянешь? Потом будешь решать что здесь и для кого в каком виде?
Fi1osof
13 августа 2019, 08:25
0
Разве не хорошо, что на modx.pro начали появляться публикации любой направленности? По-моему, это круто!
Основная масса уже выразила свое мнение (как «вслух», так и звездочками к топикам). Я пока умываю руки, пишите без меня.
Fi1osof
13 августа 2019, 07:36
0
Пожалуйста.
Fi1osof
13 августа 2019, 06:56
+2
Статусы ошибок — я так понимаю в подавляющем большинстве случаев ответ будет 200 и надо парсить тело ответа, чтобы определить что нам пришло. Не критично, но и не радует.
На сколько я знаю, в контекст выполнения запроса всегда передаются объекты запроса и ответа (во всяком случае в JS и во всяком случае в prisma.io). По этой причине нет проблемы установить свой код ответа.
me: (source, args, ctx, info) => {
ctx.response.statusCode = 500;
return {
id: «DSfdsf»
}
}
В php вообще не надо доступа к объекту ответа, там из любого положения можно задать заголовки, на сколько я помню.
Как определить что прилетевший запрос слишком жирный?
Думаю, определять именно жирность запроса нет смысла. Я уже говорил, graphql ничего не знает о том, как будет выполняться непосредственно запрос. Он только парсит схему и определяет корректно ли был запрос написан или нет. Может у вас там запрос будет query {downloadInternetLatestVersion}. С точки зрения graphql это совсем не тяжелый запрос, одна операция всего, даже без параметров.
Но выставлять различные лимиты в graphql есть возможность.
medium.com/in-the-weeds/graphql-and-resource-limitations-442c3bd72358
Можно еще, как вариант, по времени выполнения ограничить (к примеру, запросы на чтение более 3 сек — это скорее всего уже слишком много).

Контроль доступа к данным
Здесь несколько вариантов. Еще раз напомню: есть большая разница между схемой (которую обрабатывает graphql) и реальными запросами. По этой причине в большинстве случаев именно вы будете отвечать за безопасность. Но есть варианты.
1. Изучить схему через graphql-voyager habr.com/ru/company/mailru/blog/448354/
Еще до появления этой статьи я начал его активно использовать и он на сайте у меня с самого начала: prisma-cms.com/graphql-voyager
2. Непосредственно разграничение кому можно делать, а кому нельзя, это уже вам самим делать проверку. То есть есть схема Mutation.updateTopic. Вам надо будет персонализировать пользователя, проверить его ли это объект и т.п. У меня бОльшая часть базовой логики проходит через единый процессор, и там в том числе есть и проверка прав на объект.
Кеширование — как я понял из того что пока читал, организовать кеширование довольно нетривиальная задача, опять таки из-за того что непонятно какой запрос будет выполнен.
Вот это точно. И по опыту я скажу: организовывать кеширование на стороне сервера — может выйти боком, это делайте в последнюю очередь. Лучше делайте кеширование на стороне браузера. В том же apollo-client есть мощные средства для кеширования. Можете зайти на prisma-cms.com, открыть dev-tools network и посмотреть ajax-запросы. Походите по одним и тем же страницам туда-сюда, и вы увидите, что далеко не все запросы постоянно повторяются.

Целостность данных связанных сущностей при update если что-то пошло не так?
Это у меня контролирует prisma.io. Там на все создаются первичные/вторичные ключи. Когда я отправляю на апдейт запрос с вложенностями, если что-то не так на любом уровне, выполняется откат на уровне БД (transaction rollback).

Аналитика — в случае REST я могу повесить логирование каждого endpoint и спустя некоторое время, ознакомиться с полученными данными и в случае необходимости оптимизировать/переделать. В случае gql я себе смутно представляю как это сделать.
Я прям сейчас не могу ответить четко, потому что до этого плотно не дошел. Но средства уже есть, их просто надо изучить.
Вот в целом про логирование в node-js мне статья понравилась: habr.com/ru/company/funcorp/blog/461881/
Ну а непосредственно по graphql если погуглить «graphql performance monitoring», можно наверняка найти нужное. Вот, к примеру, у apollo-server есть: blog.apollographql.com/graphql-caching-and-performance-monitoring-in-minutes-with-apollo-engine-9b8e5da57bfb
Призма тоже юзает его, так что по идее средства мониторинга в ней уже есть, просто надо раскопать.

В какой-то системе а-ля CRM с кучей хитрых операций, политик доступа, повышенными требованиями к безопасности — нет.
Вот тут вы, вероятно, заблуждаетесь. В который раз говорю: graphql — это только схемы (условно). Конечная логика — это уже на вас. Даже если у вас уже есть свое REST-API, совсем не лишним будет поставить GraphQL между ним и клиентом. Логика реального выполнения запросов у вас не поменяется. Но, во-первых, у вас всегда будет перед глазами API-схема и вы всегда будете понимать что вам может клиент в запросах отправить и что получить. Во-вторых, у вас будет только одна точка входа. Вы покопайте статьи по безопасности того же MODX: там закройте, здесь прикройте, здесь подмените и т.д. и т.п. И все равно на сайте (я про подобные танцы). И даже если вы все это сделаете, все равно у вас могут остаться дыры (Вы можете не знать, что где-то в assets появился php-файл коннектор, через который весь сайт можно ломануть, как это не раз было с gallery, login, phpthumb и т.п.). А потом еще зараза проникает и вообще весь сайт как решето. В случае использования graphql у вас только одна точка входа (если вы сами не добавили еще). Посмотрите внимательно prisma-cms.com, вы можете запросы отправлять только на prisma-cms.com/api/ или api.prisma-cms.com/ (которые ведут в итоге все равно в одну точку). Больше никуда. И даже когда я использовал связку graphql+MODX, логика вся выполнялась по-прежнему в MODX, но точка входа была только одна.
Fi1osof
13 августа 2019, 05:31
0
Вот это уж точно. На хабре хоть на любой уровень читающий и собеседник найдется. А здесь многим чего попроще бы. Значительно попроще… К примеру, чуть подробней разжевать про curl в MODX, хотя говорилось про него давно уже. Но самим же 100 строк кода не осилить.
И пофигу, что там есть серьезные проблемы с установкой многих заголовков (этого просто нельзя сделать без расширения класса). Это мелочи и это не важно. Во-первых, слишком сложно. Во-вторых, все равно единицы дойдут до использования за пределами того функционала, что на блюдечке предоставлен.

А статья была своего рода «Фи». Надоело с вами тут возиться. Новые технологии никому не нужны, никто ничего не хочет учить. Ну да ладно, зато jQuery еще хоть кому-то понадобится.

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