In Nest+GrqphQL+Prisma+React Full Stack Development series, I will lead you to learn how to use these technology stacks step by step and develop a practical application.

This is the first article, GraphQL.

First introduction to GraphQL

(1) Introduction

Official definition: GraphQL is a query language for apis, a server-side runtime that executes queries using a type based system (defined by your data).

Simply put, it’s another technology for querying data through an interface, in the same vein as REST.

(2) Contrast with REST

Why do you need GraphQL when you already have REST?

REST, or Representational State Transfer, translates as Representational State transformation.

RESTful Architecture definitions:

  1. Each URI represents a resource
  2. Between the client and the server, some representation layer of this resource is passed, i.econent-typeDifferent types of
  3. The client uses four HTTP verbs to perform operations on server-side resources to achieve “presentation level state transitions,” i.eGET.POSTthese

REST’S API, coupled with JSON format data exchange, makes it easy to separate the front and back ends and interact with data, and is growing rapidly in popularity. But then the disadvantages are revealed:

  1. Interface definitions depend on documentation, which takes time to write. If the definition is missing, the front-end staff does not know how to use it
  2. Improper design results in a large number of redundant interfaces with high repetition and similarity
  3. Upgrade iteration is difficult, from the front end to the background all need to modify again
  4. It’s difficult to get all the data you need at once, and multiple requests need to be made

GraphQL lets the front end describe the data structure it needs, and the back end returns the data.

(3) Advantages and disadvantages of GraphQL

1. The advantages

  1. Data integrity, REST data is discrete, if you want to fetch the associated data, you need to send a new interface, Graph can be defined at fetch time
  2. Cache powerful, the official has helped you to achieve good, graphql.org/learn/cachi…
  3. It is easy to upgrade without modifying interfaces with different version numbers
  4. The communication cost between the front and rear ends is low
  5. No overacquisition or underacquisition
  6. Subscription accepts server-side push without relying on polling or websockets
  7. On introspection, you can query the types supported by the GraphQL server

2. The shortcomings

  1. Complexity. When retrieving an interface, if too many fields are unreasonably nested, it is easy to cause inefficient queries on the server side
  2. Unable to do query frequency limit

Second, an introduction to

(1) Basic concepts

1. Operation

GraphQL’s operations include Query, mutation, and Subscription. The general operation format looks like this

operation name(args) { 
   // Data type
}
Copy the code

Such as:

query HeroNameAndFriends {
  hero(id: "1000"){
    name
    friends {
      name
    }
  }
}
Copy the code

2. Schema

GraphQL has its own type language that defines the types of fields, the structure of data, and the rules for interface data requests.

# object type Character {name: String! appearsIn: [Episode!] ! } # parameter type Starship {length(unit: LengthUnit = METER): Float} # Query type type Query {hero(episode: episode): Character droid(id: ID!) Type Mutation {hero(episode: episode): Character Droid (id: id!) : Droid} # scalar type Int, Float,String,BooleanID # enum enum Episode {NEWHOPE EMPIRE JEDI} #id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]! Joint type} # union SearchResult = Human | Droid | Starship # input type input ReviewInput {stars: Int!
  commentary: String
}
Copy the code

3. Execution

The back end also needs to define the Resolver function to provide the data when we perform the query.

For example, a parse function for query:

Query: {
  human(obj, args, context, info) {
    return context.db.loadHumanByID(args.id).then(
      userData= > new Human(userData)
    )
  }
}
Copy the code

The parser function takes four arguments:

  • objUpper-level objects are not normally used if the field is of the root node query type.
  • argsParameters passed in.
  • contextIs provided to all parsers and holds important context information
  • infoA value that holds field-specific information and schema details related to the current query

4. Introspection

Introspection is the use of GraphQL to find out which queries are supported:

{__schema {types {name}}}__type(name: "..."){name}} #__type(name: "...") {
    name
    fields {
      name
      type {
        name
        kind
      }
    }
  }
}
Copy the code

5. The HTTP request

For example, query GET requests:

{me {name}} # HTTP request ishttp://myapi/graphql? query={me{name}}
Copy the code

The POST request is:

{
  "query": "..."."operationName": "..."."variables": { "myVariable": "someValue". }}Copy the code

All returns are JSON:

{
  "data": {... },"errors": [...]. }Copy the code

6. Paging

In GraphQL, it is generally recommended to use cursors for paging queries.

{
  hero {
    name
    friends(first:2, after:$friendId) {
      totalCount
      edges {
        node {
          name
        }
        cursor
      }
      pageInfo {
        endCursor
        hasNextPage
      }
    }
  }
}
Copy the code

Use GraphQL in Nest

First you need to install the appropriate packages

$ npm i --save @nestjs/graphql graphql-tools graphql apollo-server-express@2.x.x
Copy the code

Nest provides two ways to build GraphQL applications, schema first and code first.

Code first, which uses decorators and TypeScript classes to generate the corresponding GraphQL Schema.

Pattern first is your own GraphQL SDL (Pattern Definition Language).

Configure app.module.ts after installation

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot({}),
  ],
})
export class ApplicationModule {}
Copy the code

Use GraphQL in React

React GraphQL uses applo/client

npm install @apollo/client graphql
Copy the code

Initialization:

const client = new ApolloClient({
  uri: 'https://48p1r2roz4.sse.codesandbox.io',
  cache: new InMemoryCache()
});
Copy the code

Connect the Client to the React

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

Get data:

const EXCHANGE_RATES = gql` query GetExchangeRates { ... } `; function ExchangeRates() { const { loading, error, data } = useQuery(EXCHANGE_RATES); if (loading) return <p>Loading... </p>; if (error) return <p>Error :(</p>; return ... ) ); }Copy the code