Besides retrieving data, APIs also need to support changes or mutations to the data. There generally are three kinds of mutations:
- Creation of new data
- Update for existing data
- Deletion of data
Mutations follow the general structure of queries:
mutation { createHotel(name: "Taj", noRooms: 30) { id } }
Here the mutation has a createHotel root field, and it identifies the mutation uniquely. We are giving it the name and noRooms parameters, with the Taj and 30 values respectively. Like a query, the payload here describes what we want in terms of the properties of the newly created object; here we are asking for the ID of the new person.
Continuing with our hotel example in graphql-go, the mutation root object defines all the various mutations (update, create, delete, and so on). For example, a simple create mutation is defined as follows:
// root mutation var rootMutation = graphql.NewObject(graphql.ObjectConfig{ Name: "RootMutation", Fields: graphql.Fields{ "createHotel": &graphql.Field{ Type: hotelType,
// the return type for this field Description: "Create new hotel", Args: graphql.FieldConfigArgument{ "displayName": &graphql.ArgumentConfig{ Type: graphql.NewNonNull(graphql.String), }, "city": &graphql.ArgumentConfig{ Type: graphql.NewNonNull(graphql.String), }, "noRooms": &graphql.ArgumentConfig{ Type: graphql.NewNonNull(graphql.Int), }, "starRating": &graphql.ArgumentConfig{ Type: graphql.NewNonNull(graphql.Int), }, }, Resolve: func(params graphql.ResolveParams)
(interface{}, error) { // marshall and cast the argument value displayName, _:=
params.Args["displayName"].(string) city, _:= params.Args["city"].(string) noRooms, _:= params.Args["noRooms"].(int) starRating, _:= params.Args["starRating"].(int) // create in 'DB' newHotel:= Hotel{ Id: randomId(), DisplayName: displayName, City: city, NoRooms: noRooms, StarRating: starRating, } hotels[newHotel.Id] = newHotel // return the new Hotel object return newHotel, nil }, }, }, })
Here we use the preceding map described to store the hotel object, after generating an ID for hotel. The ID is generated using the randomId() helper function:
// Random ID Generator var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") func randomId() string { b:= make([]rune, 8) for i:= range b { b[i] = letterRunes[rand.Intn(len(letterRunes))] } return string(b) }
Note that this is not a good way of generating IDs—one big reason is the possibility of collisions. Generally when a DB is used, the ID is autogenerated as the primary key of the object.
The following CURL request shows how to create a hotel using the preceding definition:
curl -g 'http://localhost:8080/graphql?query=mutation+_{createHotel(displayName:"HotelX",city:"NY",noRooms:300,starRating:5){id}}'