General thoughts: Apollo's GraphQL's Course
Published: 2022-05-15 22:39:05

This is a public journal that would include stuff I think are necessary for me to remember. 

Previously I have been tweeting about it, but then Twitter is a private owned platform and anything could happen to my account. 

Now onto the good stuff:

1. On the Client side, the `useQuery` hook returns an object with 3 useful properties. They are destructured. The first, loading, indicates whether the query has completed and results have been returned. The second, error is an object that contains any errors that the operation has thrown. The third, data contains the results of the query after it has completed.

To set variables in our Query, we declare them in the second parameter of the `useQuery` hook, inside the options object.

Code Example using React JS:

```javascript
import { useQuery, gql } from '@apollo/client'

export const GET_TRACK = gql`
  query getTrack($trackId: ID!) {
    track(id: $trackId) {
      id
      title
      author {
        id
        name
        photo
      }
      thumbnail
      length
      modulesCount
      numberOfViews
      modules {
        id
        title
        length
      }
      description
    }
  }
`

const Track = (props) => {
   const {loading, error, data} = useQuery(GET_TRACK,{
       variables: {prop.id}
    })

return(
    //render UI
  )
}


```

2. I had to create a schema for the module type for a track, get the data from the dataSource and structure the resolver to return the required field.

I'd say the hardest part was the resolver but with some thinking, I was able to figure it out.

What I learned is that: Your resolver function should follow your schema defined. Not just willy nilly stuff.

First the schema:

```javascript
  type Module {
    id: ID!
    "the title of the particular module"
    title: String!
    length: Int
    "the url of the particular module"
    videoUrl: String!
    "the content of the particular module"
    content: String!
  }
```

and then defining the Query that would return the required module when supplied with an argument

```javascript
type Query {
    "Query to get tracks array for the homepage grid"
    tracksForHome: [Track!]!
    "a track id would return a details about a specific track"
    track(id: ID!): Track
    "a module would return details about a specific module"
    module(id: ID!): Module!
  }
```
the dataSource for the current application is a RESTAPI so I had to use a method to get the module from that.

I did that by writing:

```javascript

getModule(moduleId) {
    return this.get(`module/${moduleId}`)
  }

```

and finally the resolver. This part got me so confused because of

1. the parent parameter
2. the args parameter

I still haven't gotten the grasp of the arguments resolver functions need so it took me a bit to think through my Schema and how the Query is going to be structured.

After that, I solved it and wrote the following resolver function

```javascript
 module: (_, { id }, { dataSources }) => {
      return dataSources.trackAPI.getModule(id)
    }

//nested in a query parent
```

I just read about Mutations and how they can serve as entry points into our GraphQL Api especially if we need to write data to our server.

A fill in the gap exercise on the Apollo website resulted in this helpful paragraph.

"Queries and Mutations are both types of GraphQL `operations`. Queries are `read` operations that always `retrieve` data. Mutations are `write` operations that always `modify` data. Similar to `Query` fields, fields of the `Mutation` type are also `entry points` into a GraphQL API."


Mutations can be easy or complex depending on the return value required and the fields being modified.

For example, a simple mutation can just have one return value. Like this:

```javascript

type Mutation{
   addSpaceCat(name: String!): SpaceCat
}

```

This is because once we call the addSpaceCat mutation, we want the client to get the updated value of the SpaceCat we just mutated.

Sometimes, though, one mutation should return multiple values.

```javascript
type Mutation{
   assignMission(missionId: ID!, spaceCatId: ID!): ???
}
//what should we return
```

and so because we need to return both, we need to create a new type. This type would include

1. `code`: an `Int` that refers to the status of the response similar to an HTTP status code.
2. `success`: a `Boolean` flag that indicates whether all the updates the mutation was responsible for succedded.
3. `message`: a `String` to display information about the result of the mutation on the client side. This is useful for us if the mutation is only, well partially successful and a generic error message won't tell the whole story.

with that, we then create a new type for our mutation respose.

```javascript
type AssignMissionResponse {
   code: Int!
   Success: Boolean!
   message: String!
   spacecat: Spacecat
   mission: Mission
}
```

Regarding GraphQL Mutation:

We use hooks to send requests to our GraphQL API from a React client. To send a mutation, we use the `useMutation` hook. This returns an `array` where the first element is the `mutate function` used to trigger the mutation. The second element is an object with more information about the mutation, such as `loading`, `error` and `data`. This hook takes in a `GraphQL operation` as the first parameter. It also takes in an `options` object as the second parameter, where properties like `variables` are set.