Добро пожаловать в часть 3 серии. Вы можете найти часть-2 здесь.
Эта серия была вдохновлена этим уроком YouTube от freecodecamp.
Мы добавили еще двух авторов и несколько их книг, мутациями из части-2.
Теперь мы обновим наши операторы возврата, чтобы наши запросы снова работали. Теперь они содержат методы mongodb для получения данных. Итак, давайте отредактируем наш schema.js.
… … const BookType = new GraphQLObjectType({ name: 'Book', fields: ( ) => ({ id: { type: GraphQLID }, name: { type: GraphQLString }, genre: { type: GraphQLString }, author: { type: AuthorType, resolve(parent, args){ //return authors.find(item => item.id === parent.authorId); return Author.findById(parent.authorId); } } }) }); const AuthorType = new GraphQLObjectType({ name: 'Author', fields: ( ) => ({ id: { type: GraphQLID }, name: { type: GraphQLString }, age: { type: GraphQLInt }, books: { type: new GraphQLList(BookType), resolve(parent, args){ //return books.filter(obj => obj.authorId === parent.id); return Book.find({authorId: parent.id}); } } }) }); const RootQuery = new GraphQLObjectType({ name: 'RootQueryType', fields: { book: { type: BookType, args: { id: { type: GraphQLID } }, resolve(parent, args){ //return books.find(item => item.id === args.id); return Book.findById(args.id); } }, author: { type: AuthorType, args: { id: { type: GraphQLID } }, resolve(parent, args){ //return authors.find(item => item.id === args.id); return Author.findById(args.id); } }, books: { type: new GraphQLList(BookType), resolve(parent, args){ //return books; return Book.find({}); } }, authors: { type: new GraphQLList(AuthorType), resolve(parent, args){ //return authors; return Author.find({}); } } } }); … …
Теперь давайте проверим, правильно ли работают наши запросы. Первый запрос — получить все книги.
Следующий — получить всех авторов с их книгами.
Далее, это получить подробную информацию о книге
И последнее, чтобы получить информацию об авторе
Теперь в нашей логике есть небольшая проблема. Мы можем добавить новую книгу или автора с меньшим количеством полей. Рассмотрим приведенный ниже случай, когда мы добавляем книгу только с ее названием.
Мы также можем проверить в mongoDB.
Теперь, чтобы избежать этого, мы добавляем новое свойство GraphQL GraphQLNonNull.
Итак, откройте файл schema.js и внесите изменения, выделенные жирным шрифтом.
… … const { GraphQLObjectType, GraphQLString, GraphQLSchema, GraphQLID, GraphQLInt, GraphQLList, GraphQLNonNull } = graphql; … … const Mutation = new GraphQLObjectType({ name: 'Mutation', fields: { addAuthor: { type: AuthorType, args: { name: { type: new GraphQLNonNull(GraphQLString) }, age: { type: new GraphQLNonNull(GraphQLInt) } }, resolve(parent, args){ let author = new Author({ name: args.name, age: args.age }); return author.save(); } }, addBook: { type: BookType, args: { name: { type: new GraphQLNonNull(GraphQLString) }, genre: { type: new GraphQLNonNull(GraphQLString) }, authorId: { type: new GraphQLNonNull(GraphQLID) } }, resolve(parent, args){ let book = new Book({ name: args.name, genre: args.genre, authorId: args.authorId }); return book.save(); } } } }); … …
Теперь, если мы перейдем к нашему Graphiql, мы не сможем ничего добавить без обязательных полей.
Далее мы добавим интерфейсную логику, которая представляет собой React в нашем приложении. Итак, перейдите в свой корневой каталог и создайте клиент с помощью create-react-app.
Затем мы запускаем наш реагирующий клиент.
Теперь у нас есть клиент, работающий на порту 3000, и сервер, работающий на порту 4000.
Затем мы очищаем часть мусора, который поставляется с приложением React. В папке src client удалите все, кроме App.js, index.js и
Кроме того, используйте простой index.js, как показано ниже.
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; ReactDOM.render(<App />, document.getElementById('root'));
Теперь нужно изменить App.js, как показано ниже.
import React from 'react'; function App() { return ( <div className="main"> <h1>Top books to Read</h1> </div> ); } export default App;
И index.css, как показано ниже.
body { font-family: "Helvetica Neue", sans-serif; }
Это отобразит наше реагирующее приложение, как показано ниже.
Теперь создайте новую папку components внутри каталога src и добавьте в нее файл BookList.js.
Далее мы добавим компонент на основе класса в BookList.js.
import React, { Component } from 'react' class BookList extends Component { render() { return ( <div> <ul className="book-list"> <li>Book Name</li> </ul> </div> ) } } export default BookList;
Затем добавьте этот компонент в App.js.
import React from 'react'; import BookList from './components/BookList'; function App() { return ( <div className="main"> <h1>Top books to Read</h1> <BookList /> </div> ); } export default App;
Нам понадобится клиент GraphQL для связи, наш сервер GraphQL, и тот, который мы будем использовать, — это Apollo.
Продолжайте, остановите свой клиент и установите следующие пакеты, необходимые для клиента graphql.
npm install apollo-boost react-apollo graphql --save
Примечание. Столкнулся с проблемой после npm install apollo-boost react-apollo graphql — сохраните. Нашел решение онлайн и заключался в том, чтобы удалить папку node_modules внутри клиента и выполнить установку пряжи.
Теперь давайте начнем использовать graphql. Мы отредактируем наш файл BookList.js, чтобы получить данные с сервера graphql.
import React, { Component } from 'react'; import { gql } from 'apollo-boost'; import { graphql } from 'react-apollo'; const getBooksQuery = gql` { books { name id } } `; class BookList extends Component { render() { console.log(this.props); return ( <div> <ul className="book-list"> <li>Book Name</li> </ul> </div> ) } } export default graphql(getBooksQuery)(BookList);
При проверке того, что мы получаем через console.log, мы получаем неприятную ошибку cors.
Итак, мы установим модуль cors на наш сервер. Остановите сервер и установите его с помощью npm.
Теперь перейдите к app.js внутри папки server и добавьте cors
const express = require('express'); const graphqlHTTP = require('express-graphql'); const schema = require('./schema/schema'); const mongoose = require('mongoose'); const cors = require('cors'); const app = express(); app.use(cors()); mongoose.connect('mongodb://nabsNew:[email protected]:59546/graphql-react'); mongoose.connection.once('open', () => { console.log('Conneted to database'); }); app.use('/graphql', graphqlHTTP({ schema, graphiql: true })); app.listen(4000, () => { console.log('Listening at port 4000'); });
Теперь обновите приложение, и вы не увидите ошибку.
Теперь, когда мы получаем наши книги правильно, мы обновим наш BookList.js, чтобы книги отображались на экране.
import React, { Component } from 'react'; import { gql } from 'apollo-boost'; import { graphql } from 'react-apollo'; const getBooksQuery = gql` { books { name id } } `; class BookList extends Component { displayBooks() { var data = this.props.data; if (data.loading) { return (<div>Loading books...</div>); } else { return data.books.map(book => { return ( <li key={book.id}>{book.name}</li> ); }) } } render() { console.log(this.props); return ( <div> <ul className="book-list"> {this.displayBooks()} </ul> </div> ) } } export default graphql(getBooksQuery)(BookList);
Здесь мы добавили метод displayBooks() для отображения книг. Если вы заметили, что console.log в предыдущей части, первый раз отображается пустой список, когда загрузка имеет значение true. Мы получаем список книг только во второй части, когда loading имеет значение false.
Это завершает наш звонок, и мы получаем все наши книги, отображаемые в приложении.
На этом заканчивается часть 3 серии. Вы можете найти код здесь, в ссылке на github.
Финальную часть-4 вы можете найти здесь.