FrontMen / marvel-graphql-js

Workshop to wrap a REST API in GraphQL

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Workshop wrapping a REST API in GraphQL

Installation

Clone the repository and run npm install

npm install

Starting the server

Notice: the server will crash because you have to do assignment 2 first

npm start

Workshop

1. Marvel API

You will need an API Key which you can get from the Marvel Developer portal. You need to register an account here, to get the key. Once you have your public and private keys add them to the .env in the root directory. You are now ready to make calls to the Marvel API.

To be able to call the Marvel API you will also need a MD5 Hash. You do not need to create the hash yourself.
A Utility class MD5Util is provided to create the MD5 hash. For more information please refer to the Authorizing and signing requests section of the Marvel documentation.

2. Create your first schema + resolver combo

Assignment: Create a "Hello World!" in GraphQL

Make a change to the schema open graphql/types/schema.graphql and add a property

type Query {
  hello: String!
}

Now create the resolver open graphql/resolvers/query.js and add the resolver

const resolveFunctions = {
  Query: {
    hello() {
      return 'world!';
    },
  },
};

Now start your GraphQL API

npm start

The server will run on port localhost:8080. The server will restart automatically when you change code.

Assignment: Run a query in http://localhost:8080/graphiql that returns { data: { hello: "World!" } }

3. Get characters from the Marvel API

We've created a context variable with the Marvel API Service. This is available in the GraphQL Context.

The third parameter in a resolver is the one that provides the context that's being defined. The context is added to the resolvers as an argument in /server.js:29 on line 29.

The service is defined as a class in /services/marvel.js

Here's a code snippet to get one character by id:

const resolveFunctions = {
  Query: {
    async character(_, args, { marvel }) {
      return marvel.getCharacter(args.id);
    },
  },
};

Assignment: Make a change to the schema to be able to request both characters (plural) and character(id: Int!) and write your own resolvers. Your type should contain the properties: id, name, description

4. Add thumbnail to your character type

Now that we have a character we can also add the Thumbnail that's being returned from the Marvel API. To do so, add the following to the schema. Doing this will allow your clients to query this part from GraphQL and it'll be automatically included from the Marvel API response

type Character {
  thumbnail: Thumbnail
}

type Thumbnail {
  path: String
  extension: String
}

Assignment: Add thumbnail to your schema

5. Flatten "Thumbnail" from the Character type

Up to now we only used data from the Marvel API directly. However, it would be nice to flatten our Thumbnail into a string, so it can be used without joining the path and extension.

Assignment: Change your schema to reflect the thumbnail property of Character as a String.

6. Advanced: Add a "Favorite" workflow to your API

To create a service in /services, make a class and add it to the context /server.js. This service will be available as a property of context as the third argument in a resolver:

myResolver(parent, args, context){
  context.marvel.getCharacters();
  context.myservice.myfunction();
}

Assignment: Create a service that can track a list of "favorite" superheroes by ID. Fill it with some samle data

7. Advanced: Add a mutation to toggle a Super Hero as "Favorite"

GraphQL is a query language where the Query and Mutation model are separate from each other. It's designed so that you don't do CRUD on every type. However, every mutation returns a type of the "query model".

A schema defines a mutation in the root type Mutation

type Mutation {
  setFavorite(id: Int): Character
}

The resolver mutation is defined in /graphql/resolvers/. For example in a new file called mutations.js.

Assignment: Add a method to your custom service, to set a hero as a favorite. Use this method to implement the resolver for the mutation.

8. Advanced: Retrieve if a Hero is a favorite

To use this Favorite service, we can add a property favorite: Boolean to the Character type.

Assignment: Add favorite to Character, and retrieve it using a resolver

9. Advanced: Make a hero non-favorite

Assignment: Make a schema, resolver and service change that allows the client to un-favorite a hero.

10. Very advanced: Make a subscription

Subscriptions are used to notify a client of a change. Take a look at the example code here.

Browse the repo to get a good overview of what needs to be done.

Assignment: Make a subscription that fires whenever a Hero is favorited or un-favorited.

About

Workshop to wrap a REST API in GraphQL


Languages

Language:JavaScript 97.4%Language:Dockerfile 2.6%