# Connecting GraphQL ## to your own React project
# Jisse Reitsma - Founder of Yireo - Trainer of Magento 2 developers - Creator of MageTestFest & Reacticon - Member of ExtDN.org - Magento Master 2017 & 2018 Mover - Not really good at Adobe Photoshop
# REST in peace ## Because GraphQL is better
# Different worlds
# Monolithic Magento
# Current status of Magento - You are using Magento 2.1 or Magento 2.2 - Magento 2.3 is coming in Q4 2018 (?) - With GraphQL support - With PWA Studio (?) - Without support for checkout / cart (?) - Magento 2.4 will include everything
# GraphQL - No more underfetching or overfetching - Ask what you want to receive - Only receive what you asked for - API discovery - Discover the API while typing - Queries & Mutations - Schema stitching
# Hybrid solutions
# Hybrid solutions - PWA Studio for catalog, normal shop for checkout - Stand-alone React satellites that lead back to M2 shop - Replacing UiComponents with small React widgets - Like me, just playing around with Magento 2.3 + GraphQL + React
# Magento 2.3 setup
# Magento 2.3 setup ```bash git clone git@github.com:magento/magento2.git git checkout 2.3-develop cd 2.3-develop/ composer install ``` or ```bash composer create-project \ --repository=https://repo.magento.com/ \ magento/project-community-edition=2.3.* \ --stability=beta ```
# Magento 2.3 setup - Install Magento 2.3 - Add sample data (the GitHub procedure) - Run production mode because of exception handling - Run developer mode because of GraphQl Predictive API - My destination URL: https://magento23.yr
# Modify .htaccess ```
Header set Access-Control-Allow-Origin "http://localhost:3000" Header set Access-Control-Allow-Headers "Content-Type"
``` - Or use [Yireo_CorsHack](https://github.com/yireo-training/magento2-corshack) for this
# Let's play with GraphQL
# Hello Graphql ``` { products(search: "Hood") { items { id sku name }, filters { name:name } } } ```
# GraphQL clients - Shell command - GraphiQL client - React client - Axios - Apollo - Vulcan (full-stack Meteor-based)
# Shell test ```bash curl -X POST \ -H "Content-Type: application/json" \ -d '{"query": "{products(search: \"Hood\") { items {id,sku,name}, filters {name:name} }}"}' \ https://magento23.yr/graphql ```
# GraphiQL - In browser - In Electron - In AppImage I used GraphiQL.app (https://github.com/skevy/graphiql-app)
# Add React to the mix
# Let's create a React app! ``` create-react-app mm18uk-app1 cd mm18uk-app1/ npm start ``` And browse to http://localhost:3000/
# Axios (proof of concept)
# Axios client (1 of 2) File `src/index.js`: ```js import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import axios from 'axios'; const axiosClient = axios.create({ baseURL: "https://magento23.yr/graphql", }); ```
# Axios client (2 of 2) File `src/index.js`: ```js const SAMPLE_QUERY = `{products(search: "Hood") { items {id,sku,name}, filters {name:name} }}`; axiosClient .post('', { query: SAMPLE_QUERY }) .then(result => console.log(result.data.data.products)); ReactDOM.render(
, document.getElementById('root')); ```
# Little bug with OPTIONS Magento file `index.php`: ```php if($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { header("HTTP/1.1 200 OK"); die(); } ``` Or use Yireo_CorsHack for this
# Axios components
# And now with real components - App - ProductList
# Or even - App - ProductListContainer - ProductList - Product - ProductLink - ProductMedia
# Axios-driven component (1 of 2) ```js import React from 'react'; import axios from 'axios'; export default class ProductList extends React.Component { state = { products: [] } componentDidMount() { ... } render() { return (
{ this.state.products.map(product =>
{product.sku} {product.name}
) }
) } } ```
# Axios-driven component (2 of 2) ```js ... componentDidMount() { const SAMPLE_QUERY = `{products(search: "Hood") { items {id,sku,name}, filters {name:name}}}`; const axiosClient = axios.create({ baseURL: "https://magento23.yr/graphql", }); axiosClient.post('', { query: SAMPLE_QUERY }).then(result => { const products = result.data.data.products.items; this.setState({ products }); }) } ... } ```
# Not reusable It's hard to reuse the same Axios client in multiple components
# Tight binding between state & view - Solution: Use Container component + Presentational component
# A better approach: Apollo
# A better approach: Apollo Client ```js npm install apollo-boost react-apollo graphql-tag graphql --save ``` Follow procedure of Apollo docs
# Apollo Client architecture - `ApolloClient` is added to `ApolloProvider` as a property - `ApolloProvider` is wrapped around `App` - `ProductList` uses a `Query` component to query GraphQL
# Conclusion Once you have a Magento 2.3 development environment,
you can expose catalog data via GraphQL and start building in React
# Bonus slide - Reacticon (October 4th 2018) - Mārtiņš Saukums: VueJS component in M2 frontend - Jisse Reitsma: [ReactJS component in M2 frontend](https://github.com/yireo-training/Yireo_ReactMinicart)
# Magento 2.3 will be there soon
# Start playing with GraphQL ### @jissereitsma / jisse@yireo.com
# Bonus video: What we do with Knockout
Your browser does not support the video tag.