All streams
Search
Write a publication
Pull to refresh
15
0
Григорий Коваленко @XAHTEP26

Веб-разработчик

Send message
А в чем проблема? Есть псевдоселектор :lang для этого:

p:lang(ru) {
  quotes: "«" "»" "„" "“";
}
p:lang(en) {
  quotes: "“" "”" "‘" "’";
}

Живой пример
Не обязательно. Свойство quotes может принимать сколько угодно пар кавычек в качестве значения и они будут использоваться для вложенных кавычек:

p {
  quotes: "«" "»" "„" "“" "“" "”" "‘" "’";
}
Поддерживается font-variant пока что только в Firefox и Safari, поэтому использовать его как основную фишку дизайна не стоит.
Ошибаетесь. Именно small-caps давно поддерживается всеми современными браузерами.
Да и не современными тоже.
Насчет того что надо использовать button — согласен. А насчет остального нет.
Посмотрите как сделаны кнопки «Fork», «Settings», «Change view» на том же CodePen, где вы писали примеры. Для меня этот вариант наиболее верный.
Сейчас мне проще это сделать ибо у меня множество URI (точек входа — «дверей») которым я могу сопоставить роли.

В случае GraphQL у меня будет фактически одно URI — «одно окно» — и возникает вопрос — где мне прописывать ограничения?

Да ведь можно же ограничить сам список полей в схеме. Например, если роль «Авторизованный пользователь», то он может запрашивать поле «messages», а если «Гость», то нет (возвращать null или выводить ошибку).

И в конце концов, если вам хочется, можно сделать несколько endpoint`ов (URI/точек входа/дверей/окон) с разными схемами данных и сопоставлять им соответствующие роли.
Спасибо. Поправил и даже дополнил немного.
Начиная от доступа к URI по ролям, использование ролей при выводе результатов (уже после основного запроса/запросов) и заканчивая — ставим роль на конкретный метод сервиса (чтоб уж наверняка не «пробило»).

Вот точно так же и с GraphQL. )

Но дело в том, что мы сейчас знаем — что выдать клиенту — ибо фактически не он, а мы управляем запросом.
А вот GraphQL — тут первую скрипку ведёт клиент. И в этом то и отличие.

Клиент может выбирать какие данные запросить из тех, которые ему доступны и задавать их структуру. Вам же остается только ограничить те данные, которые доступны клиенту (как вы это и делаете сейчас) и пусть балуется.
В качестве основы для статьи я взял код написанный в предыдущих частях статьи. И там все делалось примерно так как вы написали. В этой же статье я постарался изменить код, чтобы уменьшить количество запросов (количество выполнений execute). В цикле для запроса данных о 30 пользователях вы бы отправили 30 запросов, а после описанных мною манипуляций вы бы сделали это за 1 запрос.
А нужно это для того чтобы снизить нагрузку на сервер БД и уменьшить время выполнения. Так как выполнить 1 запрос быстрее чем 30.
Вот о какой безопасно идёт речь, в случае GraphQL. Имхо.

Просто «в комментариях к предыдущей статье» в основном спрашивали про тяжелые запросы и nested attacks.

Что касается вашего вопроса:
Вот как разграничить это удобно?

Я пожалуй отвечу так: А как вы это делаете сейчас (без GraphQL)?
Также, как если бы в ответе вернулось null.
Если тип поля NonNull, то выдает ошибку: Cannot return null for non-nullable field
Если нет, то просто возвращает значение как null.
Спасибо.
Я смотрю у вас любопытная библиотека готовится. Буду следить. )
Отличная статья. Я уже начинал погружение во Vue и мне он очень понравился. Но из-за недостатка свободного времени пришлось пока отложить его. Поэтому читать статью и снова вспоминать как это красиво реализовано было приятно.
Хотелось бы еще более подробное описание про Vuex, так как без него врядли можно сделать серьезное приложение.
Я же надеюсь Вы с SQL Injection боретесь при помощи плейсхолдеров...

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

А самый правильный — это JOIN двух таблиц

Разумеется вы можете написать более сложный запрос в ресолвере поля «allUsers», добавив в него JOIN. И тогда вам даже не надо будет писать ресолвер для поля «countFriends».
Я же намеренно усложнил себе задачу, чтобы «искусственно» создать себе проблему, в которой можно будет рассказать про Deferred. Главное вы знаете что делать если в один запрос уложиться не получается, а все остальное в ваших руках.
Идея интересная, но к сожалению реализация мне не совсем понятна. Наверное мой уровень знания PHP недостаточно велик. ) Не могли бы вы привести пример использования данного класса? Или еще лучше было бы посмотреть код какого-либо проекта с использованием вашего подхода целиком, если такой есть в открытом доступе разумеется.
В данной статье я решил не использовать какой-либо конкретный фреймворк, поэтому то, что похоже на Eloquent скорее является псевдокодом и сделано так, чтобы на мой взгляд было проще понять проблему.
А вот уже на реальных проектах ваш совет будет очень полезен, про ResolveInfo я знаю, но таким образом его не использовал. Спасибо, возьму на вооружение. )
Конкретно про решение проблемы n+1 можете почитать здесь:
http://webonyx.github.io/graphql-php/data-fetching/#solving-n1-problem

Это документация к библиотеке graphql-php и в ней этот случай описан. Если все равно возникнут вопросы — задавайте.
В данном примере — да. Для каждого пользователя будет ещё отдельный запрос друзей, но как я уже писал ранее — это я сделал чтобы максимально упростить пример. Вы же можете написать любой запрос к базе данных и потом полученные результаты обработать в ресолвере как вам надо.
Насколько я знаю в реализациях GraphQL на PHP пока нет готового решения этой проблемы, но думаю в будущем она появится. А пока можно просто накладывать определённые ограничения на вложенности или время выполнения запроса. Или же создать что-то вроде реестра доступных запросов и тогда, если запроса полученного сервером не будет в реестре, то он не будет выполняться. Хороший ответ на подобный вопрос есть тут: http://stackoverflow.com/questions/37337466/how-do-you-prevent-nested-attack-on-graphql-apollo-server

Information

Rating
Does not participate
Location
Ставрополь, Ставропольский край, Россия
Date of birth
Registered
Activity