├── .gitignore ├── 01 - react-graphql ├── .env_dev ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt ├── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── GithubAPI.js │ ├── GithubGraphQL.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reportWebVitals.js │ └── setupTests.js └── yarn.lock ├── 02 - minimal-node-application ├── .babelrc ├── .gitignore ├── .prettierrc ├── .travis.yml ├── README.md ├── package-lock.json ├── package.json └── src │ └── index.js ├── 03 - apollo-client ├── .env_prod ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── GraphQL │ ├── Mutations.js │ ├── Queries.js │ ├── Subscriptions.js │ ├── apolloSetup.js │ └── index.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reportWebVitals.js │ └── setupTests.js ├── 04 - node-graplQL-application ├── .babelrc ├── .gitignore ├── .prettierrc ├── .travis.yml ├── README.md ├── package.json └── src │ ├── Mock_Data.js │ ├── Schema │ ├── Resolvers.js │ ├── TypeDefs.js │ └── index.js │ └── index.js └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | **/node_modules/ 3 | .nvmrc 4 | **/.nvmrc 5 | .env 6 | **/.env 7 | temp 8 | /.pnp 9 | .pnp.js 10 | 11 | # testing 12 | /coverage 13 | 14 | # production 15 | **/build 16 | 17 | # misc 18 | .DS_Store 19 | .env.local 20 | .env.development.local 21 | .env.test.local 22 | .env.production.local 23 | **/yarn.lock 24 | 25 | npm-debug.log* 26 | yarn-debug.log* 27 | yarn-error.log* 28 | **/package-lock.json -------------------------------------------------------------------------------- /01 - react-graphql/.env_dev: -------------------------------------------------------------------------------- 1 | REACT_APP_GITHUB_ACCESS_TOKEN=MyAccessTokenForGithub 2 | REACT_APP_HELLO_WORLD=GrpahQL Application 3 | REACT_APP_VERSION=v1.1 4 | REACT_APP_BASEURL=https://api.github.com -------------------------------------------------------------------------------- /01 - react-graphql/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-graphql", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.4", 7 | "@testing-library/react": "^11.1.0", 8 | "@testing-library/user-event": "^12.1.10", 9 | "axios": "^0.21.1", 10 | "react": "^17.0.2", 11 | "react-dom": "^17.0.2", 12 | "react-scripts": "4.0.3", 13 | "web-vitals": "^1.0.1" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": [ 23 | "react-app", 24 | "react-app/jest" 25 | ] 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.2%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 1 chrome version", 35 | "last 1 firefox version", 36 | "last 1 safari version" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /01 - react-graphql/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uqutub/graphQL/7d1949686f6aefe592052030658b52649fa9e30c/01 - react-graphql/public/favicon.ico -------------------------------------------------------------------------------- /01 - react-graphql/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /01 - react-graphql/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uqutub/graphQL/7d1949686f6aefe592052030658b52649fa9e30c/01 - react-graphql/public/logo192.png -------------------------------------------------------------------------------- /01 - react-graphql/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uqutub/graphQL/7d1949686f6aefe592052030658b52649fa9e30c/01 - react-graphql/public/logo512.png -------------------------------------------------------------------------------- /01 - react-graphql/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /01 - react-graphql/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /01 - react-graphql/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | /* text-align: center; */ 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /01 - react-graphql/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | // import GithubAPI from './GithubAPI'; 3 | import GithubGraphQL from './GithubGraphQL' 4 | 5 | function App() { 6 | return ( 7 |
8 | {/* */} 9 | 10 |
11 | ); 12 | } 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /01 - react-graphql/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /01 - react-graphql/src/GithubAPI.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | import axios from 'axios' // for API Calling 3 | 4 | const api = axios.create({ 5 | baseURL: 'https://api.github.com' 6 | }); 7 | 8 | function GithubAPI() { 9 | 10 | const [userData, setUserData] = useState(null) 11 | const [userRepos, setUserRepos] = useState(null) 12 | 13 | // componentDidMount 14 | useEffect(() => { 15 | 16 | // Immediately Invoked Function Expression - IIFE 17 | (async () => { 18 | const { data: user } = await api.get('/users/uqutub') // user Data 19 | console.log('user ', user) 20 | setUserData(user); // update state of the userData 21 | 22 | const { data: repo } = await api.get('/users/uqutub/repos') 23 | console.log('repos: ', repo) 24 | setUserRepos(repo); // update state of the userRepos // user repos 25 | })() 26 | 27 | }, []) 28 | 29 | return ( 30 |
31 | User Data 32 |
33 |                 {userData && JSON.stringify(userData, null, 4)}
34 |             
35 |
36 | User Repo Data 37 |
38 |                 {userRepos && JSON.stringify(userRepos, null, 4)}
39 |             
40 |
41 | ); 42 | } 43 | 44 | export default GithubAPI; 45 | -------------------------------------------------------------------------------- /01 - react-graphql/src/GithubGraphQL.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react' 2 | import axios from 'axios' 3 | 4 | const api = axios.create({ 5 | baseURL: 'https://api.github.com', // Github 6 | headers: { 7 | Authorization: `bearer ${process.env.REACT_APP_GITHUB_ACCESS_TOKEN}`, // access token 8 | } 9 | }); 10 | 11 | function GithubAPI() { 12 | 13 | // const fetchData_js = async (organizationName) => { 14 | // const QUERY_ORGANIZATION = `query { 15 | // organization(login: "${organizationName}") { 16 | // name 17 | // description 18 | // url 19 | // createdAt 20 | // } 21 | // viewer { 22 | // login 23 | // email 24 | // company 25 | // repositories(first: 5) { 26 | // edges { 27 | // node { 28 | // name 29 | // } 30 | // } 31 | // } 32 | // } 33 | // }`; 34 | 35 | // const res = await api.post('/graphql', { query: QUERY_ORGANIZATION }) 36 | // console.log('GraphQL Response: ', res); 37 | // } 38 | 39 | const fetchData_ql = async (organizationName) => { 40 | 41 | const QUERY_ORGANIZATION = `query queryOrganization($organizationName: String!){ 42 | organization(login: $organizationName) { 43 | name 44 | description 45 | url 46 | createdAt 47 | } 48 | viewer { 49 | login 50 | email 51 | company 52 | repositories(first: 5) { 53 | edges { 54 | node { 55 | name 56 | } 57 | } 58 | } 59 | } 60 | }`; 61 | 62 | const res = await api.post('/graphql', { 63 | query: QUERY_ORGANIZATION, 64 | variables: { 65 | organizationName 66 | } 67 | }) 68 | console.log('GraphQL Response: ', res); 69 | } 70 | 71 | const addStart = async (repositoryId) => { 72 | const MUTATION_ADD_START = `mutation AddStarToMyRepo($organizationName: ID!) { 73 | addStar(input: {starrableId: $organizationName}) { 74 | starrable { 75 | viewerHasStarred 76 | } 77 | } 78 | }`; 79 | 80 | const { data: { data } } = await api.post('/graphql', { 81 | variables: { 82 | abc: repositoryId 83 | }, 84 | query: MUTATION_ADD_START, 85 | }) 86 | console.log('GraphQL Response: ', data); 87 | } 88 | 89 | useEffect(() => { 90 | // fetchData_ql("qutbITech") 91 | addStart('MDEwOlJlcG9zaXRvcnkzODc1MTIzNjA=') 92 | }, []) 93 | 94 | 95 | 96 | return ( 97 |
98 | 99 |
100 | ); 101 | } 102 | 103 | export default GithubAPI; 104 | -------------------------------------------------------------------------------- /01 - react-graphql/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /01 - react-graphql/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /01 - react-graphql/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /01 - react-graphql/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /01 - react-graphql/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /02 - minimal-node-application/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env" 4 | ] 5 | } -------------------------------------------------------------------------------- /02 - minimal-node-application/.gitignore: -------------------------------------------------------------------------------- 1 | logfile 2 | 3 | .env 4 | 5 | node_modules/ -------------------------------------------------------------------------------- /02 - minimal-node-application/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "all", 4 | "singleQuote": true, 5 | "printWidth": 70, 6 | } -------------------------------------------------------------------------------- /02 - minimal-node-application/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - stable 5 | 6 | install: 7 | - npm install 8 | 9 | script: 10 | - npm test 11 | -------------------------------------------------------------------------------- /02 - minimal-node-application/README.md: -------------------------------------------------------------------------------- 1 | # Simple Node Application 2 | 3 | [![Build Status](https://travis-ci.org/rwieruch/minimal-node-application.svg?branch=master)](https://travis-ci.org/rwieruch/minimal-node-application) [![Slack](https://slack-the-road-to-learn-react.wieruch.com/badge.svg)](https://slack-the-road-to-learn-react.wieruch.com/) [![Greenkeeper badge](https://badges.greenkeeper.io/rwieruch/minimal-node-application.svg)](https://greenkeeper.io/) 4 | 5 | An easy way to get started with JavaScript on the command line. [Read more about it](https://www.robinwieruch.de/minimal-node-js-babel-setup). 6 | 7 | [![Edit minimal-react-webpack-babel-setup](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/rwieruch/minimal-node-application/tree/master/?fontsize=14) 8 | 9 | ## Installation 10 | 11 | * `git clone git@github.com:rwieruch/minimal-node-application.git` 12 | * `cd minimal-node-application` 13 | * `npm install` 14 | * `npm start` 15 | * optional: include *.env* in your *.gitignore* 16 | -------------------------------------------------------------------------------- /02 - minimal-node-application/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-babel-server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon --exec babel-node src/index.js", 8 | "test": "echo \"No test specified\" && exit 0" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@babel/core": "^7.2.2", 15 | "@babel/node": "^7.2.2", 16 | "@babel/preset-env": "^7.2.3", 17 | "nodemon": "^1.18.9" 18 | }, 19 | "dependencies": { 20 | "apollo-boost": "^0.4.9", 21 | "cross-fetch": "^3.1.4", 22 | "dotenv": "^8.2.0", 23 | "graphql": "^15.5.1" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /02 - minimal-node-application/src/index.js: -------------------------------------------------------------------------------- 1 | import 'dotenv/config'; // for getting .env file 2 | import 'cross-fetch/polyfill' // dependency apolo-boost 3 | import ApolloClient, { gql } from 'apollo-boost'; 4 | 5 | const client = new ApolloClient({ 6 | uri: 'https://api.github.com/graphql', // Github GraphQL Server 7 | request: operation => { 8 | operation.setContext({ 9 | headers: { 10 | authorization: `Bearer ${process.env.GITHUB_TOKEN_ACCESS}` 11 | } 12 | }); 13 | } 14 | }); 15 | 16 | 17 | // React => Axios => Github gql 18 | // Node => Apollo-boost => Github gql 19 | 20 | // const GET_ORG_DETAILS = gql` 21 | // query { 22 | // organization(login: "qutbITech") { 23 | // name 24 | // id 25 | // } 26 | // } 27 | // `; 28 | 29 | // // POST 30 | // client.query({ 31 | // query: GET_ORG_DETAILS 32 | // }).then(res => console.log('GET_ORG_DETAILS >>>', res)); 33 | 34 | 35 | // Data Scraping 36 | // AI 37 | 38 | // Server => Request (daraz => Mobile Price) => Database ???? (Client/React) 39 | 40 | // React => Server => (Database) => Response Client (UI) 41 | 42 | 43 | 44 | // // Query with Variables 45 | 46 | // const GET_ORG_DETAILS_VARIABLE = gql` 47 | // query getOrganization($org: String!, $org2: String!){ 48 | // org1: organization(login: $org) { 49 | // name 50 | // url 51 | // description 52 | // } 53 | // org2: organization(login: $org2) { 54 | // name 55 | // url 56 | // description 57 | // } 58 | // } 59 | // `; 60 | 61 | // client.query({ 62 | // query: GET_ORG_DETAILS_VARIABLE, 63 | // variables: { 64 | // org: "qutbITech", 65 | // org2: "facebook" 66 | // } 67 | // }) 68 | // .then(res => console.log('GET_ORG_DETAILS_VARIABLE >>>', res)) 69 | // .catch(err => console.log('Err: ', err)); 70 | 71 | 72 | 73 | 74 | // // MUTATION 75 | 76 | const ADD_STAR = gql` 77 | mutation AddStartToMyRepo($repoId: ID!) { 78 | addStar(input: { starrableId: $repoId }) { 79 | starrable { 80 | viewerHasStarred 81 | } 82 | } 83 | } 84 | ` 85 | 86 | client.mutate({ 87 | mutation: ADD_STAR, 88 | variables: { 89 | repoId: "MDEwOlJlcG9zaXRvcnkzODc1MTIzNjA=" 90 | } 91 | }) 92 | .then(d => console.log(JSON.stringify(d))) 93 | .catch(err => console.log('Err: ', err)); 94 | -------------------------------------------------------------------------------- /03 - apollo-client/.env_prod: -------------------------------------------------------------------------------- 1 | REACT_APP_GRAPHQL_URI=http://localhost:4000/graphql 2 | REACT_APP_GRAPHQL_WS_URI=ws://localhost:4000/graphql -------------------------------------------------------------------------------- /03 - apollo-client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "apollo-client", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@apollo/client": "^3.3.21", 7 | "@testing-library/jest-dom": "^5.11.4", 8 | "@testing-library/react": "^11.1.0", 9 | "@testing-library/user-event": "^12.1.10", 10 | "graphql": "^15.5.1", 11 | "react": "^17.0.2", 12 | "react-dom": "^17.0.2", 13 | "react-scripts": "4.0.3", 14 | "subscriptions-transport-ws": "^0.9.19", 15 | "web-vitals": "^1.0.1" 16 | }, 17 | "scripts": { 18 | "start": "react-scripts start", 19 | "build": "react-scripts build", 20 | "test": "react-scripts test", 21 | "eject": "react-scripts eject" 22 | }, 23 | "eslintConfig": { 24 | "extends": [ 25 | "react-app", 26 | "react-app/jest" 27 | ] 28 | }, 29 | "browserslist": { 30 | "production": [ 31 | ">0.2%", 32 | "not dead", 33 | "not op_mini all" 34 | ], 35 | "development": [ 36 | "last 1 chrome version", 37 | "last 1 firefox version", 38 | "last 1 safari version" 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /03 - apollo-client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uqutub/graphQL/7d1949686f6aefe592052030658b52649fa9e30c/03 - apollo-client/public/favicon.ico -------------------------------------------------------------------------------- /03 - apollo-client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /03 - apollo-client/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uqutub/graphQL/7d1949686f6aefe592052030658b52649fa9e30c/03 - apollo-client/public/logo192.png -------------------------------------------------------------------------------- /03 - apollo-client/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uqutub/graphQL/7d1949686f6aefe592052030658b52649fa9e30c/03 - apollo-client/public/logo512.png -------------------------------------------------------------------------------- /03 - apollo-client/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /03 - apollo-client/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /03 - apollo-client/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | /* text-align: center; */ 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /03 - apollo-client/src/App.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | import './App.css'; 3 | 4 | import { useQuery, gql } from '@apollo/client' 5 | import { LOAD_USERS } from './GraphQL/Queries' 6 | 7 | import { useMutation } from '@apollo/client' 8 | import { CREATE_USER_MUTATION } from './GraphQL/Mutations' 9 | 10 | import { useSubscription } from '@apollo/client' 11 | import { SUBSCRIBE_USER_ADDED } from './GraphQL/Subscriptions' 12 | 13 | 14 | function App() { 15 | 16 | const [users, setUsers] = useState([]) 17 | const [form, setForm] = useState({ name: 'aaa', age: 0, married: false }) 18 | 19 | // add user using GraphQl Mutation 20 | const [createUser, { error: mutationErr }] = useMutation(CREATE_USER_MUTATION) 21 | const addUser = () => { 22 | console.log(form) 23 | createUser({ 24 | variables: { 25 | n: form.name, 26 | a: Number(form.age), 27 | m: form.married 28 | } 29 | }) 30 | if (error) { 31 | console.log('Error on Create User....') 32 | } 33 | } 34 | 35 | // -- GraphQL SUBSCRIPTION -- 36 | const { data: userSubsDasta, error: subscriptionError, loading: subscriptionLoader } = useSubscription(SUBSCRIBE_USER_ADDED) 37 | useEffect(() => { 38 | userSubsDasta && console.log('userSubsDasta: ', userSubsDasta) 39 | if (userSubsDasta) { 40 | const newAddedUser = userSubsDasta['newUser'] 41 | const allusers = [...users] // old users 42 | allusers.unshift(newAddedUser); // push 43 | setUsers(allusers) // re-render 44 | } 45 | // logic (todo) 46 | }, [userSubsDasta]) 47 | 48 | // GraphQL Querry 49 | const { error, loading, data } = useQuery(LOAD_USERS) 50 | useEffect(() => { 51 | console.log('dataaaa', data) 52 | if (data) { 53 | setUsers(data['getAllUsers']) 54 | } 55 | }, [data]) 56 | 57 | 58 | if (loading) { 59 | return (

Loading......

) 60 | } 61 | 62 | return ( 63 |
64 |
{ 65 | const obj = { ...form }; 66 | obj[target.name] = (target.name == 'married') ? target.checked : target.value 67 | setForm(obj) 68 | }} onSubmit={(e) => { 69 | e.preventDefault(); 70 | addUser() 71 | }}> 72 | 73 | 74 | Married 75 | 76 |
77 |
 78 |         {JSON.stringify(users, null, 2)}
 79 |       
80 |
81 | ); 82 | } 83 | 84 | export default App; 85 | 86 | // getAllUser By Query 87 | // Subscription on NewUser 88 | // Mutation CreateUser 89 | 90 | // Mutation DELETE 91 | // SUBSCRITIOPN DELETE 92 | 93 | 94 | // == CACHING == 95 | // createUser({ 96 | // variables: { 97 | // name: '', 98 | // age: 26, 99 | // married: false 100 | // }, refetechQueries:[{ 101 | // query: LOAD_USERS 102 | // }] 103 | // }) 104 | 105 | // { 106 | // variables: {}, 107 | // update: (store, { data }) => { 108 | // const userData = store.readQuery({ 109 | // query: '' 110 | // }); 111 | 112 | // store.writeQuery({ 113 | // query: UsersDocument, 114 | // data: { 115 | // books: [...userData!.users, daya!.createUser] 116 | // } 117 | // }) 118 | // } 119 | // } -------------------------------------------------------------------------------- /03 - apollo-client/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /03 - apollo-client/src/GraphQL/Mutations.js: -------------------------------------------------------------------------------- 1 | import { gql } from '@apollo/client' 2 | 3 | export const CREATE_USER_MUTATION = gql` 4 | mutation createUser($n: String!, $a: Int!, $m: Boolean!) { 5 | createUser(name: $n, age: $a, married: $m) { 6 | name 7 | } 8 | } 9 | ` -------------------------------------------------------------------------------- /03 - apollo-client/src/GraphQL/Queries.js: -------------------------------------------------------------------------------- 1 | import { gql } from '@apollo/client' 2 | 3 | export const LOAD_USERS = gql` 4 | query { 5 | getAllUsers { 6 | name 7 | age 8 | married 9 | } 10 | } 11 | 12 | ` -------------------------------------------------------------------------------- /03 - apollo-client/src/GraphQL/Subscriptions.js: -------------------------------------------------------------------------------- 1 | import { gql } from '@apollo/client' 2 | 3 | export const SUBSCRIBE_USER_ADDED = gql` 4 | subscription { 5 | newUser { 6 | name 7 | age 8 | } 9 | } 10 | ` -------------------------------------------------------------------------------- /03 - apollo-client/src/GraphQL/apolloSetup.js: -------------------------------------------------------------------------------- 1 | import { WebSocketLink } from '@apollo/client/link/ws'; 2 | import { onError } from '@apollo/client/link/error' 3 | import { getMainDefinition } from '@apollo/client/utilities'; 4 | import { 5 | ApolloClient, 6 | InMemoryCache, 7 | ApolloProvider, 8 | HttpLink, 9 | from, 10 | split 11 | } from "@apollo/client" 12 | 13 | const wsLink = new WebSocketLink({ 14 | uri: process.env.REACT_APP_GRAPHQL_WS_URI, 15 | options: { 16 | reconnect: true, 17 | // connectionParams: { 18 | // authToken: '', 19 | // } 20 | } 21 | }); 22 | 23 | const httpLink = new HttpLink({ 24 | uri: process.env.REACT_APP_GRAPHQL_URI 25 | }); 26 | 27 | // https://www.apollographql.com/docs/react/data/error-handling/ 28 | const errorLink = onError(({ graphqlErrors, networkErrors }) => { 29 | if (graphqlErrors) { 30 | graphqlErrors.map(({ message, location, path }) => { 31 | alert('GraphQL Error: ' + message); 32 | }); 33 | } 34 | 35 | // To retry on network errors, we recommend the RetryLink 36 | // instead of the onError link. This just logs the error. 37 | if (networkErrors) { 38 | console.log(`[Network error]: ${networkErrors}`); 39 | } 40 | }) 41 | 42 | // The split function takes three parameters: (https://www.apollographql.com/docs/react/data/subscriptions/) 43 | // * A function that's called for each operation to execute 44 | // * The Link to use for an operation if the function returns a "truthy" value 45 | // * The Link to use for an operation if the function returns a "falsy" value 46 | const splitLink = split( 47 | ({ query }) => { 48 | const definition = getMainDefinition(query); 49 | return ( 50 | definition.kind === 'OperationDefinition' && 51 | definition.operation === 'subscription' 52 | ); 53 | }, 54 | wsLink, 55 | httpLink, 56 | ); 57 | 58 | const client = new ApolloClient({ 59 | cache: new InMemoryCache(), 60 | link: from([errorLink, splitLink]) 61 | }) 62 | 63 | export { 64 | ApolloProvider, 65 | client 66 | } -------------------------------------------------------------------------------- /03 - apollo-client/src/GraphQL/index.js: -------------------------------------------------------------------------------- 1 | export * from './apolloSetup'; 2 | export * from './Queries'; 3 | export * from './Subscriptions'; 4 | export * from './Mutations'; -------------------------------------------------------------------------------- /03 - apollo-client/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /03 - apollo-client/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | import { ApolloProvider, client } from './GraphQL/index' 7 | 8 | ReactDOM.render( 9 | 10 | 11 | 12 | 13 | , 14 | document.getElementById('root') 15 | ); 16 | 17 | // If you want to start measuring performance in your app, pass a function 18 | // to log results (for example: reportWebVitals(console.log)) 19 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 20 | reportWebVitals(); 21 | -------------------------------------------------------------------------------- /03 - apollo-client/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /03 - apollo-client/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /03 - apollo-client/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /04 - node-graplQL-application/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env" 4 | ] 5 | } -------------------------------------------------------------------------------- /04 - node-graplQL-application/.gitignore: -------------------------------------------------------------------------------- 1 | logfile 2 | 3 | .env 4 | 5 | node_modules/ -------------------------------------------------------------------------------- /04 - node-graplQL-application/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "all", 4 | "singleQuote": true, 5 | "printWidth": 70, 6 | } -------------------------------------------------------------------------------- /04 - node-graplQL-application/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - stable 5 | 6 | install: 7 | - npm install 8 | 9 | script: 10 | - npm test 11 | -------------------------------------------------------------------------------- /04 - node-graplQL-application/README.md: -------------------------------------------------------------------------------- 1 | Learn: https://www.apollographql.com/docs/apollo-server/data/subscriptions/ -------------------------------------------------------------------------------- /04 - node-graplQL-application/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-babel-server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon --exec babel-node src/index.js", 8 | "test": "echo \"No test specified\" && exit 0" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@babel/core": "^7.2.2", 15 | "@babel/node": "^7.2.2", 16 | "@babel/preset-env": "^7.2.3", 17 | "nodemon": "^1.18.9" 18 | }, 19 | "dependencies": { 20 | "@graphql-tools/schema": "^7.1.5", 21 | "apollo-server-express": "^3.0.2", 22 | "body-parser": "^1.19.0", 23 | "dotenv": "^8.2.0", 24 | "express": "^4.17.1", 25 | "graphql": "^15.5.1", 26 | "graphql-subscriptions": "^1.2.1", 27 | "http": "^0.0.1-security", 28 | "subscriptions-transport-ws": "^0.9.19" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /04 - node-graplQL-application/src/Mock_Data.js: -------------------------------------------------------------------------------- 1 | const users = [ 2 | { 3 | name: 'Paulo', 4 | age: 15, 5 | married: true 6 | }, 7 | { 8 | name: 'Angela', 9 | age: 20, 10 | married: false 11 | }, 12 | { 13 | name: 'Hassan Ali', 14 | age: 20, 15 | married: false 16 | } 17 | ]; 18 | 19 | export { users } -------------------------------------------------------------------------------- /04 - node-graplQL-application/src/Schema/Resolvers.js: -------------------------------------------------------------------------------- 1 | import {users} from '../Mock_Data' 2 | import { pubsub } from './index'; 3 | 4 | export const resolvers = { 5 | Query: { 6 | getAllUsers() { 7 | return users; 8 | } 9 | }, 10 | Mutation: { 11 | createUser(parent, args) { 12 | const newUser = args; 13 | users.push(newUser); 14 | pubsub.publish('TRIGGER_NEW_USER', { newUser }); 15 | return newUser 16 | }, 17 | deleteUser(parent, args) { 18 | const deletedUser = users.find(({ name }) => name == args.name) 19 | console.log(deletedUser) 20 | // delete user logic from an Array 21 | pubsub.publish('TRIGGER_DELETED_USER', { deletedUser }); 22 | return deletedUser 23 | } 24 | }, 25 | Subscription: { 26 | newUser: { 27 | subscribe: () => pubsub.asyncIterator(['TRIGGER_NEW_USER']) 28 | }, 29 | deletedUser: { 30 | subscribe: () => pubsub.asyncIterator(['TRIGGER_DELETED_USER']) 31 | } 32 | } 33 | 34 | }; -------------------------------------------------------------------------------- /04 - node-graplQL-application/src/Schema/TypeDefs.js: -------------------------------------------------------------------------------- 1 | import { gql } from 'apollo-server-express' 2 | 3 | export const typeDefs = gql` 4 | 5 | # Types 6 | type User { 7 | name: String! 8 | age: Int! 9 | married: Boolean! 10 | } 11 | 12 | # Queries 13 | type Query { 14 | getAllUsers: [User!]! 15 | } 16 | 17 | 18 | # Mutations 19 | type Mutation { 20 | createUser(name: String!, age: Int!, married: Boolean!): User! 21 | deleteUser(name: String!): User! 22 | } 23 | 24 | # Subscription 25 | type Subscription { 26 | newUser: User! 27 | } 28 | 29 | ` 30 | 31 | -------------------------------------------------------------------------------- /04 - node-graplQL-application/src/Schema/index.js: -------------------------------------------------------------------------------- 1 | import { resolvers } from './Resolvers' 2 | import { typeDefs } from './TypeDefs' 3 | import { PubSub } from "graphql-subscriptions"; 4 | 5 | const pubsub = new PubSub(); 6 | 7 | export { 8 | resolvers, 9 | typeDefs, 10 | pubsub 11 | } -------------------------------------------------------------------------------- /04 - node-graplQL-application/src/index.js: -------------------------------------------------------------------------------- 1 | import 'dotenv/config'; 2 | import { createServer } from "http"; 3 | import express from "express"; 4 | import { execute, subscribe } from "graphql"; 5 | import { ApolloServer, gql } from "apollo-server-express"; 6 | 7 | import { SubscriptionServer } from "subscriptions-transport-ws"; 8 | import { makeExecutableSchema } from "@graphql-tools/schema"; 9 | import { typeDefs, resolvers } from './Schema' 10 | 11 | const PORT = process.env.PORT; 12 | const app = express(); 13 | const httpServer = createServer(app); 14 | const schema = makeExecutableSchema({ typeDefs, resolvers }); 15 | const server = new ApolloServer({ schema }); 16 | 17 | (async () => { 18 | 19 | await server.start(); 20 | server.applyMiddleware({ app }); 21 | 22 | SubscriptionServer.create( 23 | { schema, execute, subscribe }, 24 | { server: httpServer, path: server.graphqlPath } 25 | ); 26 | 27 | httpServer.listen(PORT, () => { 28 | console.log( 29 | `🚀 Query endpoint ready at http://localhost:${PORT}${server.graphqlPath}` 30 | ); 31 | console.log( 32 | `🚀 Subscription endpoint ready at ws://localhost:${PORT}${server.graphqlPath}` 33 | ); 34 | }); 35 | 36 | })(); 37 | 38 | 39 | 40 | // My Rest APIs (-SAMPLE-) :) 41 | app.get('/', (req, res)=> { 42 | // Endpoint: http://localhost:4000/ 43 | res.json({ 44 | graphQL: `http://localhost:${PORT}${server.graphqlPath}`, 45 | subscription: `ws://localhost:${PORT}${server.graphqlPath}` 46 | }) 47 | }) 48 | 49 | app.get('/github/:name', (req, res)=> { 50 | // Endpoint: http://localhost:4000/github/uqutub 51 | res.json({ 52 | username: req.params.name, 53 | githutb: `https://api.github.com/users/${req.params.name}`, 54 | }) 55 | }) 56 | 57 | app.get('/queryString', (req, res)=> { 58 | // Endpoint: http://localhost:4000/queryString?name=uqutub&email=usuf52@gmail.com 59 | res.json(req.query) 60 | }) 61 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # GraphQL using React! 2 | 3 | ## Steps (for 01 - react-graphql) 4 | - Generate and copy Access Token from [Github Personal Acess Token](https://github.com/settings/tokens) 5 | - Create _.env_ file in project folder (add REACT_APP_GITHUB_ACCESS_TOKEN=accessToken) 6 | - Install AXIOS (yarn add axios) 7 | 8 | > **Note**: Github Public APIs 9 | > _Examples:_ 10 | > https://api.github.com/users 11 | > https://api.github.com/users/uqutub 12 | > https://api.github.com/users/uqutub/repos 13 | 14 | > **Note**: Github GraphQL endpoint (for educational purpose) https://api.github.com/graphql 15 | > [Github GraphQL API Documentation](https://docs.github.com/en/graphql/overview/about-the-graphql-api) 16 | > [Github GraphQL Playground/Explorer](https://docs.github.com/en/graphql/overview/explorer) 17 | 18 | > **Book:** [The Road to GraphQL by Robin Wieruch](https://bit.ly/3ijGMDQ) (Chapters 1-7) 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | https://github.com/antstackio/graphql-pagination/tree/master/api --------------------------------------------------------------------------------