GraphQL & React. Полный курс (Material-UI, Apollo, mLab)
Vložit
- čas přidán 27. 07. 2024
- #YauhenK #webDev #GraphQL #React
Всех приветствую в курсе «GraphQL».
В данном видео-курсе мы с вами разберём библиотек GraphQL. GraphQL - фактически это язык запросов или синтаксис, который описывает как запрашивать данные, созданный в компании Facebook в 2012 году. Его разработали в качестве альтернативы REST-архитектуры. Он позволяет клиенту запросить лишь желаемые данные. За все отвечает именно клиент. Т.е. GraphQL можно использовать не только на серверной, но и на клиентской стороне.
Он имеет три основные характеристики:
- Он позволяет клиенту точно указать, какие данные ему нужны.
- Облегчает агрегацию данных из нескольких источников.
- Использует систему типов для описания данных.
✒ Timeline:
✔ 0:00 - Введение
✔ 3:06 - Установка окружения
✔ 8:31 - Схема и корневой запрос
✔ 15:43 - Функция Resolve и тест запроса
✔ 23:28 - Новый тип и связь между типами
✔ 30:31 - Списки
✔ 37:11 - Мигрируем данные на mLab
✔ 43:34 - Добавляем Mongoose и обновляем Resolve
✔ 51:35 - Создаём первую мутацию
✔ 59:09 - Мутации для удаления и обновления
✔ 1:10:01 - Структура React приложения
✔ 1:16:11 - Объединяем Front-end и Back-end
✔ 1:22:04 - Отображаем реальные данный с БД
✔ 1:30:01 - Добавление элементов в БД
✔ 1:43:03 - Удаление элементов из БД
✔ 1:48:02 - Редактирование элементов в БД
✔ 1:55:26 - Поиск элементов в БД
✒ Репозиторий курса:
✔ GitHub: github.com/YauhenKavalchuk/gr...
✒ Используемые ресурсы и инструменты:
✔ Atom (Редактор кода): atom.io/
✔ Create React App (Рабочее окружение): github.com/facebook/create-re...
✔ mLab (База данных): mlab.com
✔ Material-UI (Интерфейс приложения): material-ui.com
✔ Apollo Client: www.apollographql.com/docs/re...
✒ Полезные ссылки:
✔ Graphql (Документация): graphql.org/learn/
✒ Полный список готовых и планируемых курсов:
✔ Trello: trello.com/b/R6rD7qq8
✒ Автор курса:
✔ CZcams: / yauhenkavalchuk
✔ Instagram: / yauhenkavalchuk
✔ Twitter: / yauhenkavalchuk
✔ VK: YauhenKavalchuk
✔ LinkedIn: / yauhenkavalchuk
✔ GitHub: github.com/YauhenKavalchuk
✔ VK (Группа): webdevcom
✒ Поддержать развитие канала: github.com/YauhenKavalchuk/yo...
Спасибо огромное, за интересную тему!!!! Очень нравится твой канал!!!
Спасибо большое за отзыв)
Оу, интересная тема, обязательно посмотрю. Спасибо за труды, у вас отличный канал!
Пожалуйста)
Отличный стек, жду к нему typescript и next.js
Уже есть такие курсы на канале)
Просто супер всё что надо для начало работы, Спасибо.
Пожалуйста
Спасибо! Отличный канал!
Пожалуйста)
Отличный и актуальный курс, даже своему подовану скинул, за разбиение на темы и время под видео отдельное спасибо, в общем жирный лайк и подписка!
Спасибо большое за отзыв)
Круто! С самых основ и без воды!
Спасибо за отзыв)
Тааак) я смотрю все самое полезное тут есть) это я удачно подписался)
👍
Золотой ты мой человек... спасибо!)
Пожалуйста)
Евген спасибо!!! Искал инфу по теме и нашел твое видео, круто!!!!
Пожалуйста)
Отличный курс! Спасибо за видео!
Пожалуйста
огромное Вам спасибо, очень полезное видео!
Пожалуйста)
Хороший курс. Не всё было так гладко как в видео, пришлось посидеть, поразбираться, но в целом всё удалось и базовые знания и понятие в голове есть.
Хотелось бы ещё + к этому typescript добавить.
Спасибо!)
👍 по typescript есть отдельный курс. А связку 3х технологий пока рассматривать не планирую
@@YauhenKavalchuk можно ф-ц подход разобрать) с хуками.
Очень легкое и доступное объяснение. Классно было-бы посмотреть урок про subscription на вебсокетах.
Спасибо за отзыв
Спасибо! Все очень понятно объяснено
Пожалуйста)
Спасибо большое за Ваши видео. Было бы очень интересно послушать и увидеть на практике про микросервисный фронтенд. Фреймворки Single-spa, Frint.js или что-то другое
Пожалуйста
Вы крутой, спасибо!дока докой но ваши видео очень помогают
Спасибо за отзыв)
Отлично, вечерком гляну
👍
Классный канал, спасибо!
Спасибо за отзыв
Спасибо, класс! Было бы еще полезно разобрать как работает Apollo Cache
Пожалуйста
Отличный гайд даже на текущий момент. Общее предложение принципа имеется
Спасибо)
При запуске сервера выдал ошибку: TypeError: graphqlHTTP is not a function
at Object. (G:\graphql\server\app.js:7:21) . Во второй строке надо написать так : const {graphqlHTTP} = require('express-graphql');
Это, видимо, новая версия синтаксиса. На момент записи курса была более ранняя
@@YauhenKavalchuk скорее всего да... потому что я залез в доку и там увидел....
const { graphqlHTTP } = require('express-graphql') вот так запиши
@@alekseytrump1586 а где ты нашел решение? я в документации graphql такого не нахожу. Буду очень благодарен
@@konstantinkkk8397 Не знаю какую вы официальную документацию читаете, но в документации прослойки (промежуточного) express-graphql, есть данное решение. Данное решение допилили в свое время ссылка вот github.com/graphql/express-graphql
Круто! Только сегодня учил на официалке по документам а тут вы
👍
дока это документация, а не документ))
@@VSsoviet по пасспорту
@@VSsoviet инструкции
@@VSsoviet гайдам
Спасибо 😊
Пожалуйста
О, годнота подкатила
🙂
Спасибо!
Пожалуйста
29:29 - правильнее написать parent.directorId, чтобы код продолжил работать, если айдишники фильма и режиссера не совпадают. Спасибо за ролик!
Да, это опечатка с моей стороны
@@YauhenKavalchuk я просто добавил в каждый фильм directorName
const DirectorType = new GraphQLObjectType({
name: 'Directors',
fields: () => ({
_id: { type: GraphQLID },
name: { type: GraphQLString },
age: { type: GraphQLInt },
movies: {
type: new GraphQLList(MovieType),
resolve(parent, args) {
return Movies.find({ directorName: parent.movieName })
},
},
})
});
также в квери чтоб можно было искать по имени фильма а не по id тоже
movieName: {
type: MovieType,
args: { movieName: {type: GraphQLID} },
resolve(parent, args) {
return Movies.findOne({name: args.movieName});
}
},
Cпасибо за помощь!!!!!!!!!!!!!!
Спасибо за бесплатный курс. В качестве улучшения я бы посоветовал автору вместо совета создавать руками записи на mlab (который переехал на Mongodb Atlas) выложить дамп уже созданной базы на гитхаб и люди смогут залить дамп базы на свой аккаунт в одну комманду без копирования данных руками
учту
круто!
👍
Нашел ошибку:
22:25 - здесь на parent.id, а parent.directorId.
А работает оно "верно" только по совпадению :) (у записи Id и directorID совпадают, равны 2)
Надо-бы пометить это какой-нибудь аннотацией.
Но сам курс годный, продолжаю смотреть, большое спасибо!
)
Очень годно
Отлично)
Евгений, как всегда блестяще!
Благодарю
Моё почтение!
😁👍
Класний урок. Дякую!
Пожалуйста)
у кого ошибка на 14:01 Error: Query fields must be an object with field names as keys or a function which returns such an object.
решается исправлением Query:
нужно movie обернуть в объект с ключом fields
const QueryType = new GraphQLObjectType({
name: 'Query',
fields: {
movie: {
type: MovieType,
args: { id: { type: GraphQLString } },
resolve: (parent, args) => {
}
}
}
});
Спасибо
Почему у автора такой ошибки нет?
Спасибо!
спасибо, помогло
прежде чем глянуть комментарии - пол часа мучилась, не могла понять где этот объект он просит. Огромное спасибо. Действительно на видео ошибки такой нет - может какие-то настройки были до этого (((
Ультра полезно
Благодарю
Очень толковое объяснение и демонстрация. Но застрял на 7й лекции. Уже даже склонировал твой репозиторий, подключил базу. Но ответы по 7й лекции приходят null либо пустой массив. Если нетрудно можешь обновить? Возможно по-новому нужно обрабатывать id?
Полностью всё сделал как в видео-уроке, но на седьмом уроке, у меня так и не делает запрос на фильмы или режиссеры. На фильмы выдаёт - null, а на все фильмы - пустой массив. Естественно сейчас нет уже Mlab и я использовал MangoDB, но там принцип такой-же. Вероятно что-то сделал не так, но не могу понять что именно. Уже даже на гитХабе скачал архив и по npm install загрузил все библиотеки как у автора и всё-равно :(
Очень хороший курс, Лайк! Планируешь что-нибудь выпустить по теме JAMStack, Gatsby?
Спасибо за отзыв, планирую выпустить по Gatsby
Спасибо, очень полезный курс!
Пожалуйста
Ну да, особенно когда фронтенд за тебя уже написан))) Лучше бы на 2 видео автор все разбил. Отдельно бек и отдельно фронт
@@user-yg8nh2ek6w суть курса непосредственно в связке React c GraphQL, зачем тратить время на верстку и стили? + люди,которые такой курс смотрят с большой вероятностью уже понимают как писать простые интерфейсы по типу Material UI, и это ни к чему )
@@user-zp8xz5fu2j я люблю когда все с нуля дается. Если в материал юай не работал то будешь сним сперва разбираться а не с графкьюэль
@@user-yg8nh2ek6w я понимаю,что вы это любите
Но теперь представьте, этот курс весь с нуля, вы посмотрели этот курс, все запомнили. А потом вы хотите посмотреть другой курс,посвящённый работе React + Node (Rest API), чтобы понять эту связку
А там весь фронтенд пишется с нуля) интересно будет? Познавательно?
К тому же в реальной работе все вообще иначе, в документации Apollo Graphql точно про стили никто рассказывать не будет
godno!
Спасибо
Классный курс, в репе только сервер
В репе есть ветки, которые соответствуют урокам, там весь код
@@YauhenKavalchuk спасибо
Спасибо за ваш труд!
Подскажите пожалуйста, стоит ли сейчас учить React-Redux(по видео на вашем канале) или лучше начать с GraphQL & React? (т.к. слышу от многих, что Redux устарел)
Стоит. Redux не устарел
@@YauhenKavalchuk Спасибо!)
*GraphQL* - технология доступа к серверу (БД), а *Redux* - библиотека управления состоянием приложения...
Здравствуй, очень хороший курс, спасибо за полезные видео.
у меня вопрос по установке GraphQL, если я работаю с typescript-react в проекте. Значит мне нужно устанавливать ' graphql-typescript-react --typescript' ?
Благодарю за работу.
Видимо, да
При первом подключении выводит ошибку: "message": "Expected {} to be a GraphQL schema."
В чем может быть проблема?
В описании есть ссылка на репозиторий - можете сверить код
1:29:44 - у меня не отображался список кинчиков для director в таблице по этому таймингу - решил это добавив в модель описание поля для directorId: Schema.Types.ObjectId.
В базе у меня айдишники для всех также прописаны как ObjectId. Если они прописаны как String, то и изменять не нужно
const movieSchema = new Schema({
name: String,
genre: String,
directorId:Schema.Types.ObjectId,
watched: Boolean,
rate: Number
});
Интересно, а правильней ли использовать ObjectId для перекрестных ссылок, или достаточно String? Спасибо
Полагаю, string достаточно
@@YauhenKavalchuk спасибо!
Refetch query запрашивает полный список с бд или только diff? И нет ли возможности изменить локальный стейт на success мутации?
Запрашивается полный список.
Не затруднит написать (хотя бы в двух словах), что необходимо изменить при использовании React v.17+, т.е. сейчас?
Немного поменялись импорты в Apollo и GraphQL, в комментах уже про это написали. Компоненты можно заменить на хуки, если хотите и enhancers - ХОКи в которых подключени GraphQL можно заменить на хуки с передачей аргументов. Звучит много, но если всё знать - миграция часов 5 максимум
re-query => перезапрос
Мне кажется, лучше чем резапрос :)
Возможно)
Привет! Может кто подскажет где проблема: у меня не выводится список режисеров и фильмов, loading=true всегда и выходит что в поле data нет нужных данных, как-то рендер компонента не дожидается эти данные.
К сожалению, не видя кода не могу помочь. Сверяйте с репозиторием - это максимум, что могу посоветовать
без compose мне кажется тут что-то наподобие rest получается, т.е. ничего не меняется. Нельзя распопулейтить по запросу с веба просто по одной кнопке ничего.
включи в IDE подсказку об ошибках в словах, научно фантастический триллер пишется не так, а так Sci-Fi-Thriller, курс понравился =)
🤷♂️
Крутой курс респект. Было бы не плохо дополнить курс, как вы сказали роутингом и пагинацией. Может еще что-то :)
Все названное вами оторванно от общего контекста курса, поэтому можно спокойно посмотреть другое любое видео и прикрутить роутинг и пагинацию отдельно.
29:30 что-то не понял, на что здесь именно указывает parent? почему parent.id а не parent.directorId?
Это опечатка
на 8:10 правильно будет написать const { graphqlHTTP } = require('express-graphql');
Да, это обновлённый синтаксис
29:25 - не ошибка? Вроде должно быть return directors.find(director => director.id === parent.directorId)
Да, возможно
Добил курс, спасибо. Но жаль что на классовы компонентах, вот бы на хуках то же самое... Так же остались вопросы по поводу пагинации, бэкенда, валидации, тонкостей graphql, интеграции с php. А так же всё это в связке с typescript. Пойду гуглить.
Пожалуйста
Оно конечно круто, стильно, можно, молодёжно. Но на hh в среднем 150 упоминаний на все вакансии. 150, Карл. У jquery 600 - чтобы понятно было.
¯\_(ツ)_/¯
Есть вопрос, почему не создавали схему вот таким образом?
var schema = buildSchema(`
type Query {
hello: String
}
`);
Не совсем понимаю что не так в моих вариантах создания
у никого в начале запуска приложение не разбивалось?[nodemon] app crashed - waiting for file changes before starting...
Sergei Fediukov спс бро
А как сделать, чтобы запросы шли например на айпишку?
Добавить например fetch, как и в любых других компонентах
на 8 минуте ошибка, должно быть const {graphqlHTTP} = require(`express-graphql`) и сервер стартует
Это новый синтаксис, а не ошибка. На момент записи урока, как вы можете видеть, всё работало ок
const { graphqlHTTP } = require('express-graphql');
теперь надо писать так. иначе сервак падает в самом начале, не успев встать...
👍
Не могу понять зачем здесь используется recompose. Почему нельзя подключить graphql сразу в нужном компоненте?
Скажем так, это "задел" на возможное расширение функциональности этого приложения
@@YauhenKavalchuk Понял, спасибо. А с появлением функциональных компонентов, использовать recompose является распостраненной практикой на сегодняшний день или все-таки это уже как пережитки прошлого?
не совсем понятно как реализовываются вложенные мутации, например если бы у movie был бы массив тегов например, как его мутировать - неужели нужно теги создавать отдельным объектом и привязывать их через id
Нет, на самом деле, тут уже вопрос больше не к GraphQL, а к формату организации и хранения БД, а так же к схемам и MongoDB.
Скажите пожалуйста, в видео разобран SSR?
Нет. SSR разобран в курсе по Next.JS, вышел на канале, совсем недавно
@@YauhenKavalchuk спасибо за ответ и за видео. там все таки ssr из коробки)
я правильно понимаю что mlab больше не существует и нужно просто БД на atlass создать?
Верно
теперь список директоров не выводит. а список фильмов выводит
{
"data": {
"directors": []
}
}
на сервере пишет что режиссеры есть
Не видя полного кода, я не могу сказать в чём проблема
Что за шрифт у идеешке?? как називается?
Если честно, то уже и не помню(
Grpc for web? он будет поинтересней GrahQL
Понятия не имею
Для тех кто переделывает данный пример уже с новыми пакетами:
"apollo-server-express": "^3.1.2"
"mongoose": "^5.13.7"
там где идёт разделение на отдельно typeDefs и resolvers, в резольверах придётся описать как заполнять поле director для его отображения в составе Movie при запросе.
//для заполнения поля director в схеме Movie нужно выполнить следующий код в резольвере для movies
Movie: {// название типа в схеме graphQL
director: async(parent, args, context, info) => {//parent - родительский.
return (await parent.populate('director').execPopulate()).director//заполнить и вернуть director
}
}
//Для нахождения и заполнения массива фильмов созданных данным режиссёром: в резольвере для director добавить следующий код
Director: {// название типа в схеме graphQL
//поле-[массив] movies в типе Director
movies: async (director, args, context, info) => {//director - родительский для поля movies
//Найти фильмы (в коллекции/модели Movies) по по значению поля director = id данного (из модели Directors)
return (await Movies.find({ director: director.id }))
}
}
👍
@@YauhenKavalchuk Оказывается exec() используется с запросом всех, а .execPopulate () используется с одним документом. Нужно это учитывать. И в каждом резольвере использовать соответствуючий вариант. Пришлось закомментировать общий резольвер для Movie и прописать в запросе на все фильмы след. конструкцию:
async allMovies(parent, args, { Movies }, info) {
try {
-> const allMovies = await Movies.find().populate({path: 'director'}).exec()
return allMovies
} catch (error) {
throw new Error(error)
}
},
а в обработках запроса ОДНОГО фильма по id или создании фильма:
async movie(_, { movieId }, { Movies }) {
try {
//проверить - есть-ли такой фильм
const movie = await Movies.findById(movieId)
if (movie) {//если есть, то:
-> return movie.populate({path: 'director'}).execPopulate()
} else {
//если такого фильма нет то:
throw new Error('Фильм не найден')
}
} catch (error) {
throw new Error(error)
}
}
на конец 2022 актуальный курс?
Актуально, чуть поменялся импорт подключения, а так всё ок
А что за шрифт такой прикольный в атоме?
Честно говоря, уже не помню(
А gql точно уменьшает нагрузку на сервер? Уверены? Меня терзают смутные сомнения...
Пишут, что уменьшает) Не нужно запрашивать данные полностью, а можно порционально. Это 100% снижает. А вот на счёт количества запросов - это под вопросом
@@YauhenKavalchuk А что насчет оптимизации глубоих запросов к базе? Бэкендер не сможет их оптимизировать при росте проекта - вот я про что.
А почему на классах? Вроде год всего, тогда на функциональном не "современнее" было писать?
Это перезалив, оригинальному курсу 3 года, тогда хуков не было
@@YauhenKavalchuk ааа, ну. Всё равно спасибо. Мне очень зашло. Спустя год понадобился )
👍
блин, и тут новая проблема "_id" : "ObjectId(62b8b1717cd270632ca1ed7d)", вот такие айдишники на сервере. как это всё связать с нашим монгустом? не проходят запросы.
Ещё раз повторюсь, не видя кода, не могу подсказать решение. Максимум что могу посоветовать это сравнить ваш код и код из репозитория
решили проблему?
у меня тоже сейчас такое(
@@user-lf7sg3ju2z да. она сама как-то решилась) просто сел на другой день отдохнувший
Что за шрифт стоит в редакторе ?
Честно говоря уже и не помню
01:18:04 - рисуем остаток совы)
На самом деле данный курс о GraphQL, поэтому и не рассказывал имплементацию приложения. Только интеграцию GraphQL в React. Если вы смотрели отдельный курс по React на канале, то с пониманием кода проблем быть не должно
Эксперемент с форматами?
czcams.com/play/PLNkWIWHIRwMF2sVLwzRef0Cu5kzAOeRcu.html
Да
Вот нифига не создал базу БД, не фортануло мне
Бывает....
@@YauhenKavalchuk всё ок. это оказывается теперь иначе всё там работает.
Ребят, я один такой , кто не смог войти в mLab?
¯\_(ツ)_/¯
Был-бы вообще красавчик, если-бы переснял видео уже с современными реалиями и используя пакет "apollo-server-express": "^3.1.2". Цены бы тебе не было...
Подумаю об обновлении курса
тут интереснее было бы с тайпскриптом
По TypeScript отдельный курс
Из видео совершенно не понял преимуществ graphQL перед rest - что там для каждого отдельного действия прописывать свой адрес, что здесь свою мутацию. Те же яйца, только в профиль.
GraphQL позволяет это делать на клиенте. Плюс конфигурировать ответ именно теме полями, которые нужны для странице. А не полностью возвращать данные
немного режет глаз старый ES5 в серверной части и классовые компоненты в реакте . Вероятно это сделано чтобы избежать лишних настроек компиляции, но в 2020 году уже без ES6/2015 на сервере никак и реакт уже в 2020 году не писали на классовых компонентах. Люди могут посмотреть ролик и реально начать писать по стандартам 5-7 летней давности
Этот курс - это перезалив. Оригинальный курс писался, когда хуков ещё не было
Добавил в "Смотреть позже".
Потом отпишусь
👍
@@YauhenKavalchuk Часть "Новый тип..."
return directors.find(director => director.id == parent.directorId)
так правильнее) ошибка
четвертый урок, (director => director.id === args.id); здесь тройное равенство не убрали, запрос не работает. ну как так можно. эх... зачем айди заворачивать в строки?
Не заметил (