Recently, I finished a new project and wanted to learn something new. I heard that GraphQL is becoming popular and replacing traditional Restful apis, so I decided to learn.

What is a GraphQL

GraphQL is a query language created by Facebook for the API (the query language is not a standard SQL-like query language, but a specification for the way data is queried at the front and back ends). GraphQL is both a query language for the API and a runtime for your data queries. GraphQL provides an easy-to-understand set of complete descriptions of the data in your API, enabling a client to get exactly what it needs without any redundancy, making it easier for the API to evolve over time, and for building powerful developer tools.Copy the code

You can read more about GraphQL here

Since GraphQL is just a set of specifications, it can’t be used directly, but the community has many implementations of programming languages that can be used directly. I chose Apollo.

What is the Apollo,

Apollo is a collection of full stack solutions based on GraphQL. Apollo-client and Apollo-server; The corresponding lib is provided from the back end to the front end to make it easier to develop GraphQL.Copy the code

GraphQL needs both the front and back ends to really work, so we’ll implement it on the server side, using Apollo-Server.

Apollo-server is a Web middleware that builds GraphQL server on Node.js. Support express, KOA, HAPI and other frameworks. I’m using KOA here.

First, we need to install the dependency packages

yarn add koa koa-bodyparser koa-router apollo-server-koa graphql graphql-tools
//or
npm install koa koa-bodyparser koa-router apollo-server-koa graphql graphql-tools
Copy the code

Then, write the code

// server.js

const Koa = require('koa');
const Body = require('koa-bodyparser');
const router = require('koa-router') (); const {graphqlKoa, graphiqlKoa} = require('apollo-server-koa');
const {makeExecutableSchema} = require('graphql-tools');
const { GraphQLScalarType } = require('graphql');
const { Kind } = require('graphql/language'); const app = new Koa(); const PORT = 8090; Const users = [{id: 1, name:'J.K. Rowling',
    date: new Date(2018, 5, 20)
  },
  {
    id: 2,
    name: 'Michael Crichton',
    date: new Date(2018, 5, 21)
  },
];

const typeDefs = `
    scalar Date
    type User{
        id:Int!
        name:String!
        date: Date!
    }
    typeQuery { users(id:Int!) : [User] user(id:Int! , name: String!) :User }typeMutation { addUser(name:String!) :User } schema { query: Query mutation: Mutation } `; Const resolvers = {Query: {// corresponds totypeIn the Defstype Query
        users(root, args, context) {
            return users;
        },
        user(root, args, context, info) {
          return{id: args.id, name: args.name}; }}, Mutation: {// corresponding totypeMutation addUser(root, args, context) {return{id: 2, name: args.name}; }}, Date: new GraphQLScalarType({// custom scalar type name:'Date',
        description: 'Date custom scalar type',
        parseValue(value) {
          returnnew Date(value); // Data from the client}, serialize(value) {returnvalue.getTime(); // Data sent to the client}, parseLiteral(ast) {if (ast.kind === Kind.INT) {
            return parseInt(ast.value, 10); 
          }
          returnnull; }})}; const myGraphQLSchema = makeExecutableSchema({typeDefs,
    resolvers
});

app.use(Body());

router.post('/graphql', graphqlKoa({
    schema: myGraphQLSchema,
}));
router.get('/graphql', graphqlKoa({ schema: myGraphQLSchema, })); Router.get (// use GraphiQL in the browser.'/graphiql',
  graphiqlKoa({
    endpointURL: '/graphql',})); app.use(router.routes()); app.use(router.allowedMethods()); app.listen(PORT, ()=>console.log('app run in localhost:' + PORT));
Copy the code

Next, execute the following command to get our server running:

node server.js
app run in localhost:8090
Copy the code

Then type http://localhost:8090/graphiql in the browser, you will see the following interface:

GraphQL

The server has been successfully started, and the next step is our client. The React framework is used in the front end. For convenience, create-React-app is directly used to create the project.

After creating the project, we go to the project directory and install the dependency packages required by the client GraphQL query:

yarn add react-apollo graphql-tag graphql apollo-client apollo-cache-inmemory apollo-link-http
// or
npm install react-apollo graphql-tag graphql apollo-client apollo-cache-inmemory apollo-link-http
Copy the code

SRC /index.js: SRC /index.js

// src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { ApolloProvider } from 'react-apollo';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';

const httpLink = new HttpLink({ uri: 'http://localhost:8090/graphql' })

const client = new ApolloClient({
  link: httpLink,
  cache: new InMemoryCache()
})

ReactDOM.render(
  <ApolloProvider client={client}>
    <App />
  </ApolloProvider>
, document.getElementById('root'));
registerServiceWorker();
Copy the code

Then modify the code in SRC/app.js:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import gql from 'graphql-tag';
import { graphql } from 'react-apollo';

class App extends Component {
  render() {
    console.log(this.props);
    const { loading } = this.props.data;
    if (loading) {
      return<div>Loading... </div> }return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro"> To get started, edit <code>src/App.js</code> and save to reload. </p> <p>{this.props.data.user.name}</p> </div> ); }}export default graphql(gql`
  query User{
    user(id: 100, name: "zhangsfs") {
      id
      name
    }
    users(id: 100) {
      id
      name
      date
    }
  }
`)(App);
Copy the code

Often wrapped App components are injected with props named Data, which contains the following fields:

loading
true
false

Then run the front-end code:

yarn start
// Compiled successfully!
// You can now view client inThe browser. / / Local: / / http://localhost:8081/ On Your Network: http://172.22.228.1:8081/Copy the code

After entering http://localhost:8081/ in the browser, we found that the page reported an error and did not work properly. We opened the developer tool and found one of the errors:

So how do you implement cross-domain access? We need to modify the server code to support cross-domain access.

Add a dependency package to the server first:

yarn add @koa/cors@2
Copy the code

Then modify the server.js code:

// server.js

const Koa = require('koa');
const Body = require('koa-bodyparser');
const router = require('koa-router') (); const cors = require('@koa/cors'); . app.use(Body()); app.use(cors()); . app.listen(PORT, ()=>console.log('app run in localhost:' + PORT));
Copy the code

Then restart the server code, refresh http://localhost:8081/, and see that the project is working. A simple GraphQL query is now complete.

Write in the last

Above is just a very simple GraphQL query demo, because I am also a beginner, a lot of things are still learning stage. If you have any good development experience, welcome to exchange.