Creación de API de GraphQL con Vue.js y Apollo Client

Introducción

GraphQL es un lenguaje de consulta orientado a gráficos escrito por Facebook. A diferencia de las API de REST, GraphQL introduce características que hacen que el desarrollo de API sea más eficiente y en sintonía con los modelos de base de datos.

Características de GraphQL

  • A diferencia de REST , solo hay un punto final al que se enviarán todas las solicitudes. Entonces, en lugar de consultar /userspara obtener una lista de usuarios o /user/:idpara obtener un usuario en particular, el punto final se verá como /graphqlpara todas las solicitudes.
  • En GraphQL, los datos que regresan de una respuesta están establecidos por la biblioteca de consultas establecida y se puede configurar para enviar solo unas pocas propiedades de datos, por lo tanto, las consultas en GraphQL tienen un mejor rendimiento.
  • No es necesario configurar los verbos de método en GraphQL. Las palabras clave como Query o Mutation decidirán qué realizará la solicitud.
  • Las rutas de la API REST generalmente son manejadas por un controlador de ruta. En GraphQL puede hacer que una única consulta active múltiples mutaciones y obtenga una respuesta compuesta de múltiples fuentes.

Consultas

Una consulta es un método GraphQL que nos permite CONSEGUIMOS datos de nuestra API. Aunque puede recibir parámetros para filtrar, ordenar o simplemente buscar un documento en particular, una consulta no puede mutar estos datos.

Mutaciones

Las mutaciones son todo lo que no es lo que se referiría a un verbo GET en las API regulares. La actualización, creación o eliminación de datos de nuestra API se realiza mediante mutaciones

Suscripciones

Con el uso de sockets web, una suscripción se refiere a una conexión entre el cliente y el servidor.
El servidor está constantemente observando las mutaciones o consultas que se adjuntan a una suscripción en particular, y comunicará cualquier cambio al cliente en tiempo real. Las suscripciones se utilizan principalmente para aplicaciones / widgets en tiempo real.

Tipos y entradas

Para asegurarnos de que nuestras consultas y mutaciones puedan procesar los datos para consultar una base de datos, typesfuncionan como un ORM modelo para bases de datos. Al configurar los tipos , podemos definir el tipo de variable que devolverán nuestros resolutores.
De manera similar, necesitamos establecer tipos de entrada para que nuestros resolutores reciban.
Por ejemplo, definiremos una pareja typesinputs:
type User {  
  id: ID
  name: String!
  age: Int!
  address: Address
  followers: [ID]
}

type Address {  
  street: String
  city: String
  country: String
}

input UserInput {  
  name: String!
  age: Int!
}

type Query {  
  getAllUsers: [User]
}

type Mutation {  
  createUser(user: UserInput!): ID
}
Las propiedades pueden tener un tipo personalizado como su tipo aparte de los primitivos, como:
  • Cuerda
  • En t
  • Flotador
  • Booleano
  • CARNÉ DE IDENTIDAD
Y también pueden ser una matriz de un determinado tipo determinado por los corchetes, que se muestra en el ejemplo anterior.
Además, el estado obligatorio de una propiedad se puede establecer con el !, lo que significa que la propiedad debe estar presente.

Resolvers

Estas son las acciones que se realizan cuando se realizan consultas y mutaciones.
getAllUserscreateUserse conectarán a un resolutor que realizará los cálculos reales y las consultas de la base de datos.

Creando nuestro proyecto

Para este tutorial, crearemos un proyecto Vue.js utilizando Vue CLI 3.0 , que iniciará un proyecto con una estructura de carpetas que se ve así:
Si necesita ayuda para configurar el proyecto, puede consultar este tutorial para la interfaz de línea de comandos.
Podemos comenzar a servir nuestra aplicación con el comando:
$ npm run serve

Apollo Client

Apollo Client ofrece una herramienta para el desarrollo de aplicaciones para facilitar las consultas / mutaciones de GraphQL. Actúa como un cliente HTTP que se conecta a una API GraphQL y proporciona almacenamiento en caché, manejo de errores e incluso capacidades de administración de estado.
Para este tutorial, se utilizará Vue-Apollo , que es la integración de Apollo diseñada especialmente para Vue.js.

Configuración de Apolo

Para iniciar la configuración de Apollo, será necesario instalar algunos paquetes:
$ npm install apollo-client apollo-link-http apollo-cache-inmemory vue-apollo graphql graphql-tag
Dentro de una /graphqlcarpeta en nuestro proyecto, crearemos apollo.js:
// apollo.js

import Vue from 'vue'  
import { ApolloClient } from 'apollo-client'  
import { HttpLink } from 'apollo-link-http'  
import { InMemoryCache } from 'apollo-cache-inmemory'  
import VueApollo from 'vue-apollo'

const httpLink = new HttpLink({  
    uri: process.env.VUE_APP_GRAPHQL_ENDPOINT
})

// Create the apollo client
export const apolloClient = new ApolloClient({  
    link: httpLink,
    cache: new InMemoryCache(),
    connectToDevTools: true
})

// Install the Vue plugin

Vue.use(VueApollo)

export const apolloProvider = new VueApollo({  
    defaultClient: apolloClient
})
HttpLinkes un objeto que requiere una uripropiedad, que se refiere al punto final GraphQL de la API que se está utilizando. Ex:localhost:8081/graphql
Luego, se ApolloClientdebe crear una nueva instancia, donde se pueden configurar el enlace, la instancia de caché y otras opciones.
Finalmente, envolvemos nuestro ApolloClientinterior en una VueApolloinstancia para que podamos usar sus ganchos dentro de nuestros componentes Vue.
Manejo de errores globales
Existe una forma de manejar los errores globalmente dentro del archivo de configuración. Para eso necesitamos instalar un paquete npm llamado apollo-link-error, que inspecciona y administra los errores de la red:
// apollo.js

import Vue from 'vue'  
import { ApolloClient } from 'apollo-client'  
import { HttpLink } from 'apollo-link-http'  
import { onError } from "apollo-link-error"  
import { InMemoryCache } from 'apollo-cache-inmemory'  
import VueApollo from 'vue-apollo'

const httpLink = new HttpLink({  
    uri: process.env.VUE_APP_GRAPHQL_ENDPOINT
})

// Error Handling
const errorLink = onError(({ graphQLErrors, networkError }) => {  
    if (graphQLErrors)
        graphQLErrors.map(({ message, locations, path }) =>
            console.log(
                `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
            )
        )
    if (networkError) console.log(`[Network error]: ${networkError}`)
})

// Create the apollo client
export const apolloClient = new ApolloClient({  
    link: errorLink.concat(httpLink),
    cache: new InMemoryCache(),
    connectToDevTools: true
})

// Install the Vue plugin
Vue.use(VueApollo)

export const apolloProvider = new VueApollo({  
    defaultClient: apolloClient
})
Después de importar la onErrorfunción del paquete, podemos implementarla como una especie de middleware de Apollo Client. Atrapará cualquier error de la red o GraphQL, dándonos la oportunidad de gestionarlos globalmente.
La devolución de llamada se llama con un objeto con algunas propiedades cada vez que se produce un error:
  • operación : la operación que activó la devolución de llamada porque se encontró un error.
  • Respuesta : El resultado de la operación.
  • graphQLErrors : una matriz de errores desde el punto final GraphQL
  • error de red : cualquier error durante la ejecución de la operación o error del servidor.
  • adelante : el siguiente enlace referenciado en la cadena.

Managing State con Apollo Client

Una alternativa diferente al uso de Vuex con los proyectos de Vue, y al usar el Cliente Apollo es usar un paquete llamado apollo-link-state.
Funciona como una herramienta de administración de datos local que funciona como si estuviera consultando un servidor, pero lo hace localmente.
Además, es una excelente manera de administrar la memoria caché para nuestra aplicación, lo que convierte a Apollo Client en un cliente HTTP y una herramienta de administración de estado / memoria caché.
Para más información, puede consultar la documentación oficial de Apollo-link-state .

Creando Consultas

Para crear consultas necesitamos configurar una etiqueta de tipo cadena con el paquete graphql-tag . Para mantener un proyecto ordenado y estructurado, crearemos una carpeta llamadaqueries dentro de la carpeta graphql.
Suponiendo que el servidor que recibe la consulta está configurado correctamente para interpretar esta consulta, por ejemplo, podemos activar un resolvedor llamado getAllUsers:
import gql from 'graphql-tag'

export const GET_ALL_USERS_QUERY = gql`  
  query getAllUsers {
    getAllUsers {
      // Fields to retrieve
      name
      age
    }
  }
`
La operación por defecto en GraphQL es query, por lo que elquery palabra clave es opcional.
Si un campo recuperado tiene subcampos, entonces al menos uno de ellos debe buscarse para que la consulta tenga éxito.

Utilizando mutaciones

Al igual que las consultas, también podemos usar mutaciones creando un archivo gql-string.
import gql from 'graphql-tag'

export const CREATE_USER_MUTATION = gql`  
  mutation createUser($user: UserInput!) {
    createUser(user: $user)
  }
`
Nuestra createUsermutación espera una UserInputentrada y, para poder utilizar los parámetros pasados ​​por Apollo. Primero definiremos una variable con la $llamada userEntonces, la envoltura exterior pasará la variable a lacreateUser mutación, como lo espera el servidor.
Fragmentos
Para mantener nuestras gql-typecadenas ordenadas y legibles, podemos utilizar fragmentos para reutilizar la lógica de consulta.
fragment UserFragment on User {  
  name: String!
  age: Int!
}

query getAllUsers {  
  getAllUsers {
    ...UserFragment
  }
}

Usando GraphQL en componentes Vue

Dentro del main.jsarchivo, para configurar el cliente Apollo, necesitamos importar y adjuntar el cliente a nuestra instancia.
// main.js
import Vue from 'vue'  
import { apolloProvider } from './graphql/apollo'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({  
    el: '#app',
    apolloProvider,
    render: h => h(App)
})
Dado que hemos agregado nuestro ApolloProvider a la instancia de Vue, podemos acceder al cliente a través de la $apollopalabra clave:
// GraphQLTest.vue
<template>  
    <div class="graphql-test">
        <h3 v-if="loading">Loading...</h3>
        <h4 v-if="!loading">{{ getAllUsers }}</h4>
    </div>
</template>

<script>  
import { GET_ALL_USERS_QUERY } from '../graphl/queries/userQueries'  
export default {  
    name: 'GraphQLTest',
    data () {
        return {
            users: []
        }
    },
    async mounted () {
        this.loading = true
        this.users = await this.$apollo.query({ query: GET_ALL_USERS_QUERY })
        this.loading = false
    }
}
</script>  
Si queremos crear un usuario, podemos utilizar un mutation:
// GraphQLTest.vue
<template>  
    <div class="graphql-test">
        <input v-model="user.name" type="text" placeholder="Name" />
        <input v-model="user.age" placeholder="Age" />
        <button @click="createUser">Create User</button>
    </div>
</template>

<script>  
import { CREATE_USER_MUTATION } from '../graphl/queries/userQueries'  
export default {  
    name: 'GraphQLTest',
    data() {
        return {
            user: {
                name: null,
                age: null
            }
        }
    },
    methods: {
        async createUser () {
            const userCreated = await this.$apollo.mutate({
                mutation: CREATE_USER_MUTATION,
                variables: {
                    user: this.user // this should be the same name as the one the server is expecting
                }
            })
            // We log the created user ID
            console.log(userCreated.data.createUser)
        }
    }
}
</script>  
El uso de este enfoque nos permite realizar una microgestión cuando y donde se ejecutarán nuestras mutaciones y consultas. Ahora veremos otras formas de manejar estos métodos que Vue Apollo nos brinda.

El objeto de Apolo

Dentro de nuestros componentes de Vue, obtenemos acceso al Apolloobjeto, que se puede utilizar para administrar fácilmente nuestras consultas y suscripciones:
<template>  
    <div class="graphql-test">
        {{ getAllUsers }}
    </div>
</template>

<script>  
import { GET_ALL_USERS_QUERY } from '../graphl/queries/userQueries'  
export default {  
    name: 'GraphQL-Test',
    apollo: {
        getAllUsers: {
            query: GET_ALL_USERS_QUERY
        }
    }
}
</script>  
Recopilando consultas
Al definir una consulta dentro del objeto Apollo, es posible recuperar esta consulta cuando se llama una mutación u otra consulta con el refetchmétodo o la refetchQueriespropiedad:
<template>  
    <div class="graphql-test">
        {{ getAllUsers }}
    </div>
</template>

<script>  
import { GET_ALL_USERS_QUERY, CREATE_USER_MUTATION } from '../graphl/queries/userQueries'  
export default {  
    name: 'GraphQL-Test',
    apollo: {
        getAllUsers: {
            query: GET_ALL_USERS_QUERY
        }
    },
    methods: {
        refetch () {
            this.$apollo.queries.getAllUsers.refetch()
        },
        queryUsers () {
            const user = { name: Lucas, age: 26 }
            this.$apollo.mutate({
                mutation: CREATE_USER_MUTATION,
                variables: {
                    user
                }
                refetchQueries: [
                    { query: GET_ALL_USERS_QUERY }
                ]
            })
        }
    }
}
</script>  
Usando el Apolloobjeto, proporcionado por Vue-Apollo. , ya no necesitamos utilizar de forma activa la forma en que el cliente de Apollo activa las consultas / suscripciones, y algunas propiedades y opciones útiles están disponibles para nosotros.
Propiedades del objeto apolo
  • consulta : este es elgql cadena de tipo que se refiere a la consulta que desea que se active.
  • variables : un objeto que acepta los parámetros que se pasan a una consulta determinada.
  • fetchPolicy : una propiedad que establece la forma en que la consulta interactuará con el caché. Las opciones son cache-and-networknetwork-onlycache-onlyno-cachestandbyy el valor predeterminado es cache-first.
  • pollInterval : tiempo en milisegundos que determina con qué frecuencia se activará automáticamente una consulta.
Opciones especiales
  • $ error para detectar errores en un manejador de conjuntos.
  • $ deep observa profundamente los cambios en una consulta.
  • $ omitir : deshabilita todas las consultas y suscripciones en un componente dado.
  • $ skipAllQueries : deshabilita todas las consultas de un componente.
  • $ skipAllSubscriptions : deshabilita todas las suscripciones en un componente.

Componentes de apolo

Inspirado en la forma en que se implementa el cliente Apollo para React ( React-Apollo ), Vue-Apollo nos proporciona algunos componentes que podemos utilizar de forma inmediata para administrar la interfaz de usuario y el estado de nuestras consultas y mutaciones con un componente Vue en su interior. la plantilla.
ApolloQuery
Una forma más sencilla de gestionar nuestras consultas de una manera más intuitiva:
<ApolloQuery  
  :query="GET_ALL_USERS_QUERY"
>
    <template slot-scope="{ result: { loading, error, data } }">
        <!-- Loading -->
        <div v-if="loading">Query is loading.</div>

        <!-- Error -->
        <div v-else-if="error">We got an error!</div>

        <!-- Result -->
        <div v-else-if="data">{{ data.getAllUsers }}</div>

        <!-- No result (if the query succeed but there's no data) -->
        <div v-else>No result from the server</div>
    </template>
</ApolloQuery>  
ApolloMutation
Muy similar al ejemplo anterior, pero debemos activar la mutación con la mutatellamada a la función:
<ApolloMutation  
  :mutation="CREATE_USER_MUTATION"
  :variables="{
    name,
    age
  }"
  @done="mutationFinished"
>
    <template slot-scope="{ mutate, loading, error }">
        <!-- Loading -->
        <h4 v-if="loading">The mutation is loading!</h4>

        <!-- Mutation Trigger -->
        <button @click="mutate()">Create User</button>

        <!-- Error -->
        <p v-if="error">An error has occurred!</p>
    </template>
</ApolloMutation>  

Conclusión

GraphQL brinda mucha flexibilidad para el desarrollo de API, desde el rendimiento, la facilidad de uso y una perspectiva global diferente de cómo debería verse y comportarse una API. Además, ApolloClient y Vue Apollo ofrecen un conjunto de herramientas para una mejor administración de nuestra interfaz de usuario, estado y operaciones, ¡incluso manejo de errores y caché!
Para obtener más información sobre GraphQL y Apollo Client, puede visitar lo siguiente:

Acerca de: Programator

Somos Instinto Programador

0 comentarios:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

Con tecnología de Blogger.