Giter VIP home page Giter VIP logo

netflix-clone-vue-graphql's Introduction

Vue 3 + Apollo + GraphQL + TypeScript + Vite

Stack:

Introduction

  1. Clone repository
    git clone https://github.com/mousemckill/netflix-clone-vag-stack.git
  2. Navigate to folder with source code
    cd netflix-clone-vag-stack
  3. Install dependencies
    yarn
    or
    npm install
  4. Run dev
    yarn dev
    or
    npm run dev

Setup

  1. Install dependencies

    yarn add @vue/apollo-composable graphql @apollo/client apollo-link-rest

    or

    npm install @vue/apollo-composable graphql @apollo/client apollo-link-rest
  2. Get TMDB API key

Work with code

  1. Create Apollo Client Create file src/apolloClient.ts and add
     import { ApolloClient, InMemoryCache } from "@apollo/client/core";
     import { RestLink } from "apollo-link-rest";
    
     const API_KEY = import.meta.env.VITE_API_KEY;
    
     const customFetch = (uri: RequestInfo, options: RequestInit) => {
       return fetch(`${uri}?api_key=${API_KEY}`, options);
     };
    
     const restLink = new RestLink({
       uri: "https://api.themoviedb.org/3",
       customFetch,
     });
    
     const cache = new InMemoryCache();
    
     export const apolloClient = new ApolloClient({
       link: restLink,
       cache,
     });
  2. Connect Apollo Client to Vue Open src/main.ts and replace all to
    import { createApp, provide, h } from "vue";
    import { DefaultApolloClient } from "@vue/apollo-composable";
    
    import App from "./App.vue";
    import { apolloClient } from "./apolloClient";
    
    import "./index.css";
    
    const app = createApp({
      setup() {
        provide(DefaultApolloClient, apolloClient);
      },
      render: () => h(App),
    });
    
    app.mount("#app");
  3. Create file src/graphql/schema.graphql
    directive @type(name: String!) on FIELD
    directive @type(name: String!) on FIELD
    directive @rest(path: String!, type: String) on FIELD
    
    type Movie {
      title: String!
      backdrop_path: String!
      id: Int!
    }
    
    type MovieFull {
      id: Int
      title: String
      backdrop_path: String
      release_date: String
      overview: String
      vote_average: Int
      vote_count: Int
    }
    
    type MoviePayload {
      results: Movie
    }
    
    type Query {
      trendingMovies: MoviePayload!
      nowPlayingMovies: MoviePayload!
      originalMovies: MoviePayload!
      topRatedMovies: MoviePayload!
      popularMovies: MoviePayload!
      upcomingMovies: MoviePayload!
      movie(id: String!): MovieFull!
    }
    
    schema {
      query: Query
    }
  4. Create file src/graphql/queries/getUpcomingMovies.ts
    import { gql } from "@apollo/client/core";
    
    export const UPCOMING_MOVIES_QUERY = gql`
      query getUpcomingMovies {
        upcomingMovies @rest(path: "/movie/upcoming") {
          results @type(name: "Movie") {
            title
            backdrop_path
            id
          }
        }
      }
    `;
  5. Open file src/components/UpcomingMovies.vue and replace all to
    <script setup lang="ts">
    import { useQuery } from "@vue/apollo-composable";
    
    import MoviesSection from "./MoviesSection.vue";
    import { UpcomingMovies } from "../typings/Movie";
    import { UPCOMING_MOVIES_QUERY } from "../graphql/queries/getUpcomingMovies";
    
    const { result } = useQuery<UpcomingMovies>(UPCOMING_MOVIES_QUERY);
    </script>
    
    <template>
      <MoviesSection
        v-if="result"
        title="Upcoming"
        :items="result.upcomingMovies.results"
      />
    </template>
  6. Repeat 4 and 5 steps for other components contains MovieSection
  7. Create file src/graphql/queries/getMovie.ts
    import { gql } from "@apollo/client/core";
    
    export const MOVIE_QUERY = gql`
      query getMovie($id: String!) {
        movie(id: $id) @rest(type: "Movie", path: "/movie/{args.id}") {
          id
          title
          backdrop_path
          release_date
          overview
          vote_average
          vote_count
        }
      }
    `;
  8. Edit file src/components/MoviePreview.vue
    const props = defineProps<{
      id: number;
    }>();
    
    const { result } = useQuery<{ movie: FullMovie }>(MOVIE_QUERY, {
      id: props.id,
    });

Recommended IDE Setup

Recommended browser extension

Type Support For .vue Imports in TS

Since TypeScript cannot handle type information for .vue imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in .vue imports (for example to get props validation when using manual h(...) calls), you can enable Volar's Take Over mode by following these steps:

  1. Run Extensions: Show Built-in Extensions from VS Code's command palette, look for TypeScript and JavaScript Language Features, then right click and select Disable (Workspace). By default, Take Over mode will enable itself if the default TypeScript extension is disabled.
  2. Reload the VS Code window by running Developer: Reload Window from the command palette.

You can learn more about Take Over mode here.

TMDB HTTP endpoints

TMDB API_URL - https://api.themoviedb.org/3

Movie Details

GET {API_URL}/movie/338953?api_key={API_KEY} HTTP/1.1

Popular movies

GET {API_URL}/movie/popular?api_key={API_KEY} HTTP/1.1

Top Rated movies

GET {API_URL}/movie/top_rated?api_key={API_KEY} HTTP/1.1

Now playing movies

GET {API_URL}/movie/now_playing?api_key={API_KEY} HTTP/1.1

Upcoming movies

GET {API_URL}/movie/upcoming?api_key={API_KEY} HTTP/1.1

Trending movies

GET {API_URL}/trending/movie/week?api_key={API_KEY} HTTP/1.1

netflix-clone-vue-graphql's People

Contributors

vanoraco avatar

Watchers

 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.