Mutación (Mutation)

Una consulta en GraphQL solo realiza operaciones de lectura (READ), las mutaciones nos permiten realizar otras operaciones tales como crear (CREATE), actualizar (UPDATE) y eliminar (DELETE).

Creando una mutación simple

import express from 'express'
import graphqlHTTP from 'express-graphql'
import { GraphQLSchema,
  GraphQLObjectType,
  GraphQLID,
  GraphQLString,
  GraphQLInt,
  GraphQLBoolean,
  GraphQLNonNull,
  GraphQLList } from 'graphql'

const Authors = [{
  id: '8dlx7ak38fd39dv79ad',
  name: 'Isiah Hamilton',
  twitterHandle: '@isiah2000'
},
{
  id: 'jd3kd03d0w9a0l35rh74',
  name: 'Giovanni Harvey',
  twitterHandle: '@gio_har'
},
{
  id: '0hy894hf0dlkfh9oinv',
  name: 'Lawrence Rhodes',
  twitterHandle: '@rhodes'
}]

const Videos = [{
  id: '1',
  title: 'Mattis ullamcorper velit sed ullamcorper',
  duration: 180,
  watched: false,
  author_id :'0hy894hf0dlkfh9oinv'
},
{
  id: '2',
  title: 'Habitasse platea dictumst vestibulum',
  duration: 240,
  watched: true,
  author_id :'jd3kd03d0w9a0l35rh74'
},
{
  id: '3',
  title: 'Urna et pharetra pharetra massa massa',
  duration: 160,
  watched: false,
  author_id :'8dlx7ak38fd39dv79ad'
},
{
  id: '4',
  title: 'Eu facilisis sed odio morbi',
  duration: 260,
  watched: true,
  author_id :'0hy894hf0dlkfh9oinv'
}]

const getVideoById = (id) => new Promise((resolve) => {
  const [video] = Videos.filter((video) => {
    return video.id === id
  })

  resolve(video)
})

const getVideos = () => new Promise((resolve) => resolve(Videos))

const createVideo =({ title, duration, watched, author_id }) => {
  const
    id = Videos.length + 1,
    video = {
      id : id.toString(),
      title,
      duration,
      watched,
      author_id
    };

  // Save on memory
  Videos.push(video)

  return video
}

const app = express()

const AuthorType = new GraphQLObjectType({
  name: 'Author',
  description: 'Represent a Author.',
  fields: {
    id: {
      type: new GraphQLNonNull(GraphQLString),
      description: 'Id of the author.'
    },
    name: {
      type: new GraphQLNonNull(GraphQLString),
      description: 'Name of the author.'
    },
    twitterHandle: {
      type: GraphQLString,
      description: 'Twitter name account.'
    }
  }
})

const VideoType = new GraphQLObjectType({
  name: 'Video',
  description: 'Represent a Video.',
  fields: {
    id: {
      type: GraphQLID,
      description: 'Id of the video.'
    },
    title: {
      type: GraphQLString,
      description: 'Title of the video.'
    },
    duration: {
      type: GraphQLInt,
      description: 'Duration of the video.'
    },
    watched: {
      type: GraphQLBoolean,
      description: 'Whether or not the viewer has watch the video.'
    },
    author: {
      type: AuthorType,
      description: 'Author information.',
      resolve: (parent) => {
        return Authors.find(author => author.id == parent.author_id)
      }
    }
  }
})

const query = new GraphQLObjectType({
  name: 'Query',
  description: 'Application Schema Query Root.',
  fields: () => ({
    authors: {
      type: new GraphQLList(AuthorType),
      description: 'List of all Authors.',
      resolve: function() {
        return Authors
      }
    },
    videos: {
      type: new GraphQLList(VideoType),
      description: 'List of all Videos.',
      resolve: getVideos
    },
    video: {
      type: VideoType,
      description: 'Single video.',
      args: {
        id: {
          type: new GraphQLNonNull(GraphQLID),
          description: 'Id of the video.'
        }
      },
      resolve: (_, args) => {
        return getVideoById(args.id)
      }
    }
  })
})

const mutation = new GraphQLObjectType({
  name: 'Mutation',
  description: 'The root mutation type.',
  fields: {
    createVideo: {
      type: VideoType,
      args: {
        title: {
          type: new GraphQLNonNull(GraphQLString),
          description: 'The title of the video.'
        },
        duration: {
          type: new GraphQLNonNull(GraphQLInt),
          description: 'The duration of the video (in seconds).'
        },
        watched: {
          type: new GraphQLNonNull(GraphQLBoolean),
          description: 'Whether or not the video is released.'
        },
        author_id: {
          type: new GraphQLNonNull(GraphQLID),
          description: 'Author id.'
        }
      },
      resolve: (_, args) => {
        return createVideo(args)
      }
    }
  }
})

const schema = new GraphQLSchema({
  query,
  mutation
})

app.use('/graphql', graphqlHTTP({
  schema,
  rootValue: root,
  graphiql: true
}))

app.listen(3000, () => {
  console.log(`Server listening on port ${PORT}`)
})

Query:

mutation {
  createVideo(
    title: "Foo", 
    duration: 300, 
    watched: false,
    author_id: "8dlx7ak38fd39dv79ad"
  ) {
    title
    duration
    watched
    author {
      name
    }
  }
}

Utilizando GraphQLInputObjectType

Este método nos permite definir mutaciones mas complejas, por ejemplo aquellas entradas de datos el cual nosotros en el diseño de aplicación tienen que ser mandatorias.

const VideoInputType = new GraphQLInputObjectType({
  name: 'VideoInput',
  fields: {
    title: {
      type: new GraphQLNonNull(GraphQLString),
      description: 'The title of the video.'
    },
    duration: {
      type: new GraphQLNonNull(GraphQLInt),
      description: 'The duration of the video (in seconds).'
    },
    watched: {
      type: new GraphQLNonNull(GraphQLBoolean),
      description: 'Whether or not the video is released.'
    },
    author_id: {
      type: new GraphQLNonNull(GraphQLID),
      description: 'Author id.'
    }
  }
})

const mutation = new GraphQLObjectType({
  name: 'Mutation',
  description: 'The root mutation type.',
  fields: {
    createVideo: {
      type: VideoType,
      args: {
        // common used the word "input" instead "video"
        video : {
          type: new GraphQLNonNull(VideoInputType)
        }
      },
      resolve: (_, args) => {
        return createVideo(args.video)
      }
    }
  }
})

Query:

mutation {
  createVideo(video: {
    title: "Foo", 
    duration: 300, 
    watched: false,
    author_id: "8dlx7ak38fd39dv79ad"
  }) {
    title
    duration
    watched
    author {
      name
    }
  }
}

Nombres de mutaciones

Nombrar mutaciones puede ser un desafío. Es de buena practica utilizar verbo primero o la acción. Ejemplo: createUser, updateStories.

results matching ""

    No results matching ""