REST
GraphQL
...additionally (if there's time)
[
{
"quote_id": "rkz1GwOOM",
"movie_id": "tt0468569",
"description": "I'm Batman"
},
{
"quote_id": "rkz1GwOAS",
"movie_id": "tt0468569",
"description": "Why so serious?"
},
]
[
{
"movie_id": "tt0468569",
"title": "The Dark Knight",
"year": "2008",
"plot": "When the menace known as The Joker emerges from his mysterious past, he wreaks havoc and chaos on the people of Gotham. The Dark Knight must accept one of the greatest psychological and physical tests of his ability to fight injustice.",
"poster": "https://m.media-amazon.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_SX300.jpg",
"rated": "PG-13",
"runtime": "152 min"
},
]
movies.json
quotes.json
MovieList.js
Movie.js
MovieCreate.js
const { ApolloServer, gql } = require('apollo-server');
const fs = require('fs')
const moviesData = JSON.parse(fs.readFileSync('./data/movies.json', 'utf8'))
const quotesData = JSON.parse(fs.readFileSync('./data/quotes.json', 'utf8'))
const resolvers = {
Mutation: {
createMovie:(_,{input}) => {
// let result = db.movies.create({...input})
// return result
input.movie_id = Math.random().toString(36).substring(7); // random string
return input;
}
},
Query: {
movies: () => {
return moviesData
},
movie: (_, {movie_id}) => {
return moviesData.find(x => x.movie_id === movie_id)
}
},
Movie: {
quotes: (movie) => {
return quotesData.filter(y => y.movie_id === movie.movie_id)
}
}
}
const typeDefs = gql`
type Mutation {
createMovie(input: MovieInput): Movie
}
type Query {
movies: [Movie]
movie(movie_id: ID): Movie
}
type Movie {
movie_id: ID,
title: String,
year: String,
plot: String,
poster: String,
rated: String,
runtime: String,
quotes: [Quote],
}
type Quote {
quote_id: ID,
description: String,
}
input MovieInput {
title: String,
year: String,
plot: String,
}
`;
const server = new ApolloServer({ typeDefs,resolvers });
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
const fs = require('fs')
const moviesData = JSON.parse(
fs.readFileSync('./data/movies.json', 'utf8')
)
const quotesData = JSON.parse(
fs.readFileSync('./data/quotes.json', 'utf8')
)
const { ApolloServer, gql } = require('apollo-server');
const server = new ApolloServer({ typeDefs,resolvers });
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
const typeDefs = gql`
type Query {
movies: [Movie]
}
type Movie {
movie_id: ID,
title: String,
year: String,
plot: String,
poster: String,
rated: String,
runtime: String,
quotes: [Quote],
}
type Quote {
quote_id: ID,
description: String,
}
`
[
{
"quote_id": "rkz1GwOOM",
"movie_id": "tt0468569",
"description": "I'm Batman"
},
]
[
{
"movie_id": "tt0468569",
"title": "The Dark Knight",
"year": "2008",
"plot": "When the menace known as The Joker emerges from his mysterious past, he wreaks havoc and chaos on the people of Gotham. The Dark Knight must accept one of the greatest psychological and physical tests of his ability to fight injustice.",
"poster": "https://m.media-amazon.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_SX300.jpg",
"rated": "PG-13",
"runtime": "152 min"
},
]
const typeDefs = gql`
type Query {
movies: [Movie]
}
type Movie {
movie_id: ID,
title: String,
year: String,
plot: String,
poster: String,
rated: String,
runtime: String,
quotes: [Quote],
}
type Quote {
quote_id: ID,
description: String,
}
`
const resolvers = {
Query: {
movies: () => {
return moviesData
},
movie: (_, {movie_id}) => {
return moviesData.find(x => x.movie_id === movie_id)
}
},
}
query {
movies {
title
year
}
}
const resolvers = {
Mutation: {
createMovie:(_,{input}) => {
input.movie_id = Math.random().toString(36).substring(7); // random string
return input;
}
},
Query: {
movies: () => {
return moviesData
},
movie: (_, {movie_id}) => {
return moviesData.find(x => x.movie_id === movie_id)
}
},
Movie: {
quotes: (movie) => {
return quotesData.filter(y => y.movie_id === movie.movie_id)
}
}
}
import React from 'react';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
import { ApolloProvider } from '@apollo/react-hooks';
import ApolloClient from 'apollo-boost';
// Components
import {Movie} from './components/Movie';
import {MovieCreate} from "./components/MovieCreate";
import {MovieList} from "./components/MovieList";
const client = new ApolloClient({
uri: 'http://localhost:4000/',
});
const App = () => {
return (
<ApolloProvider client={client}>
<Router>
<div className="App">
<div>
<Link className="title" to={`/`}>Movie Quotes</Link>
</div>
<Switch>
<Route exact path="/" component={MovieList}/>
<Route exact path="/movie/create" component={MovieCreate}/>
<Route path="/movie/:movieId" component={Movie}/>
</Switch>
</div>
</Router>
</ApolloProvider>
);
}
export default App;
import React from 'react'
import {Link} from "react-router-dom"
import movieData from '../data/movies.json'
import quotesData from '../data/quotes.json'
export const MovieList = () => {
return (
<div className="movie-wrapper">
<Link className="btn-add-new" to={`/movie/create`}>+ Add New Movie</Link>
<div className="movie-list">
{movieData.map(movie => {
return (
<div className="movie-item">
<img src={movie.poster} />
<section>
<h3>{movie.title}</h3>
<p>{movie.year}</p>
<ul>
{quotesData.map(quote => {
if (quote.movie_id === movie.movie_id) {
return (
<li key={quote.quote_id}>
{quote.description}
</li>
)
}
})}
</ul>
<Link className="btn-normal" to={`/movie/${movie.movie_id}`}>Movie Details</Link>
</section>
</div>
)
})}
</div>
</div>
)
}
import React from 'react'
import movieData from '../data/movies.json';
import quotesData from '../data/quotes.json';
export const Movie = (props) =>{
const {movieId} = props.match.params; //windows
const filteredMovie = movieData.find(x=> x.movie_id === movieId)
const quotes = quotesData.filter(y => y.movie_id === movieId)
return (
<div className="movie-item single-movie">
<img src={filteredMovie.poster} />
<section>
<h3>{filteredMovie.title}</h3>
<p>{filteredMovie.year}</p>
<ul>
{quotes.map(quote => {
if (quote.movie_id === filteredMovie.movie_id) {
return (
<li key={quote.quote_id}>
{quote.description}
</li>
)
}
})}
</ul>
<p>PLOT: {filteredMovie.plot}</p>
</section>
</div>
)
}
import React, {useState} from 'react'
import Swal from 'sweetalert2'
export const MovieCreate = () =>{
const [plot, setPlot] = useState('');
const [title, setTitle] = useState('');
const [year, setYear] = useState('');
const onSubmit = event => {
event.preventDefault();
Swal.fire({
type: 'success',
html: `
<p>Title: ${title}</p>
<p>Year: ${year}</p>
<p>Plot: ${plot}</p>`
})
}
return (
<div className="movie-create">
<form onSubmit={onSubmit}>
<label>Title</label>
<input
type="text"
onChange={(e) => setTitle(e.target.value)}
/>
<label>Year</label>
<input
type="text"
onChange={(e) => setYear(e.target.value)}
/>
<label>Plot</label>
<textarea
type="text"
onChange={(e) => setPlot(e.target.value)}
/>
<button className="btn-normal" type="submit">Submit</button>
</form>
</div>
)
}
import ApolloClient from 'apollo-boost';
const client = new ApolloClient({
uri: 'http://localhost:4000/',
});
import { ApolloProvider } from '@apollo/react-hooks';
const App = () => {
return (
<ApolloProvider client={client}>
<div>Hello World!</div>
</ApolloProvider>
)
}
import { gql } from 'apollo-boost';
const GET_MOVIES = gql`
query {
movies {
movie_id
title
year
plot
poster
quotes {
quote_id
description
}
}
}
`;
import { useQuery } from '@apollo/react-hooks';
export const MovieList = () => {
const {loading, error, data} = useQuery(GET_MOVIES);
if (loading) return <p>Loading...</p>
if (error) return <p>Error ...</p>
return (
<div>
{data.movies.map(movie =>{
<h2>{movie.title}</h2>
})}
</div>
)
}
1.Frontend
2.Backend
query {
movies {
title
year
quotes {
description
}
}
}
type Query {
movies: [Movie]
}
3.Backend
const resolvers = {
Query: {
movies: () => {
return moviesData
},
},
Movie: {
quotes: (movie) => {
return quotesData.filter(y => y.movie_id === movie.movie_id)
}
}
}
5.Frontend
type Movie {
movie_id: ID,
title: String,
year: String,
plot: String,
poster: String,
rated: String,
runtime: String,
quotes: [Quote],
}
type Quote {
quote_id: ID,
description: String,
}
4.Backend
const resolvers = {
Query: {
movies: () => {
return moviesData
},
},
Movie: {
quotes: (movie) => {
return quotesData.filter(y => y.movie_id === movie.movie_id)
}
}
}