Giter Site home page Giter Site logo

odyssey-apollo-graphql's Introduction

Catstronauts (LIFT-OFF PART 1)

Full-stack tutorial from Apollo's new learning platform Odyssey.

Here is how it'll look like when we're finished Catstronauts Screenshot

Clone the repository

git clone https://github.com/apollographql/odyssey-lift-off-part1 apollographql

Project structure

In apollographql/,

πŸ“¦ catstronauts-demo
┣ πŸ“‚ client
┃ ┣ πŸ“‚ public
┃ ┣ πŸ“‚ rc
┃ ┃ ┣ πŸ“‚ assets
┃ ┃ ┣ πŸ“‚ components
┃ ┃ ┣ πŸ“‚ containers
┃ ┃ ┣ πŸ“‚ pages
┃ ┃ ┣ πŸ“‚ utils
┃ ┃ ┣ πŸ“„ index.js
┃ ┃ β”— πŸ“„ styles.js
┃ ┣ πŸ“„ README.md
┃ ┣ πŸ“„ package.json
┣ πŸ“‚ server
┃ ┣ πŸ“‚ src
┃ ┃ ┣ πŸ“„ index.js
┃ ┣ πŸ“„ README.md
┃ ┣ πŸ“„ package.json
β”— πŸ“„ README.md

Install Packages

In both server/ and client/ folder:

npm install

Concurrently

Inside apollographql folder,

Init npm:

npm init -y

Install concurrently package:

npm i -D concurrently

Add the script below in package.json:

"scripts": {
    "start": "concurrently \"cd client && npm start\" \"cd server && npm run start\""
}

Ready to run client/ and server/ at the same time.

In apollographql/:

npm start

Feature Data Requirements

The mockup

Catstronaut Mockup

Catstronauts Track Card Data

Catstronauts Data Graph


Schema defintion language (SDL)

Schema Definition Language

Define a SpaceCat type with the following fields: name of type String (non null), age of type Int, and missions of type List of Mission

const typeDefs = gql`
  """
  block description
  """
  type SpaceCat {
    "normal description"
    name: String!
    age: Int
    missions: [Mission]
  }
`;

Building our schema

const { gql } = require('apollo-server');

const typeDefs = gql`
  type Query {
    "Query to get tracks array for the homepage grid"
    tracksForHome: [Track!]!
  }
  "A track is a group of Modules that teaches about a specific topic"
  type track {
    id: ID!
    "the track's title"
    title: String!
    "the track's main author"
    author: Author!
    "the tracks' main illustration to display in track card or track page detail"
    thumbnail: String
    "the track's approximate length to complete, in minutes"
    length: Int
    "the number of modules this track contains"
    modulesCount: Int
  }

  "Author of a complete Track"
  type Author {
    id: ID!
    "Author's first and last name"
    name: String!
    "Author's profile picture url"
    photo: String
  }
`;

module.exports = typeDefs;

Apollo Server

const { ApolloServer, MockList } = require('apollo-server');
const typeDefs = require('./schema');

const mocks = {
  Query: () => ({
    tracksForHome: () => new MockList([6, 9]),
  }),
  Track: () => ({
    id: () => 'track_01',
    title: () => 'Astro Kitty, Space Explorer',
    author: () => {
      return {
        name: 'Grumpy Cat',
        photo:
          'https://res.cloudinary.com/dety84pbu/image/upload/v1606816219/kitty-veyron-sm_mctf3c.jpg',
      };
    },
    thumbnail: () =>
      'https://res.cloudinary.com/dety84pbu/image/upload/v1598465568/nebula_cat_djkt9r.jpg',
    length: () => 1210,
    modulesCount: () => 6,
  }),
};
const server = new ApolloServer({
  typeDefs,
  mocks,
});

server.listen().then(({ url }) => {
  console.log(`
  πŸš€  Server is running!
  πŸ”‰  Listening at ${url}
  πŸ“­  Query at https://studio.apollographql.com/dev
  `);
});

React App

πŸ“‚client
  ┣ πŸ“‚src
  ┃ ┣ πŸ“‚assets
  ┃ ┣ πŸ“‚components
  ┃ ┣ πŸ“‚containers
  ┃ ┣ πŸ“‚pages
  ┃ ┣ ...
  ┣ ...
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import GlobalStyles from './styles';
import Pages from './pages';
import { ApolloProvider, ApolloClient, InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  url: 'http://localhost:4000',
  cache: new InMemoryCache(),
});

ReactDOM.render(
  <ApolloProvider client={client}>
    <GlobalStyles />
    <Pages />
  </ApolloProvider>,
  document.getElementById('root')
);

Defining a query

// client/src/pages/tracks.js
import React from 'react';
import { Layout } from '../components';
import { gql } from '@apollo/client';

const TRACKS = gql`
  query getTracks {
    tracksForHome {
      id
      title
      thumbnail
      length
      modulesCount
      author {
        id
        name
        photo
      }
    }
  }
`;

/**
 * Tracks Page is the Catstronauts home page.
 * We display a grid of tracks fetched with useQuery with the TRACKS query
 */
const Tracks = () => {
  return <Layout grid> </Layout>;
};

export default Tracks;

The useQuery hook

// client/src/pages/tracks.js
import React from 'react';
import { Layout } from '../components';
import { useQuery, gql } from '@apollo/client';
import TrackCard from '../containers/track-card';
import QueryResult from '../components/query-result';

const TRACKS = gql`
  query getTracks {
    tracksForHome {
      id
      title
      thumbnail
      length
      modulesCount
      author {
        id
        name
        photo
      }
    }
  }
`;

/**
 * Tracks Page is the Catstronauts home page.
 * We display a grid of tracks fetched with useQuery with the TRACKS query
 */

const Tracks = () => {
  const { loading, error, data } = useQuery(TRACKS);

  if (loading) return 'Loading...';

  if (error) return `ERROR! ${error.message}`;

  return (
    <Layout grid>
      <QueryResult error={error} loading={loading} data={data}>
        {data?.tracksForHome?.map((track) => (
          <TrackCard key={track.id} track={track} />
        ))}
      </QueryResult>
    </Layout>
  );
};

export default Tracks;

It is the end of the first part of the Catstronauts

*The resources used in this tutorial are from Odyssey.

odyssey-apollo-graphql's People

Contributors

brandonwie avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.