NextJS 및 Graphql이 포함된 풀스택 웹 응용 프로그램
NextJS 및 Graphql이 포함된 풀스택 웹 응용 프로그램
ReactJS를 사용하여 프런트엔드 응용 프로그램을 개발하는 것에 대해 논의할 때 세 가지 주요 옵션을 찾을 수 있습니다.CRA
, 단일 웹 응용 프로그램 구축에 전념하지만 CEO 포지셔닝에 어려움이 있습니다.Gatsby
, 정적 사이트 생성에 전념, 뛰어난 성능, 멋진 CEO와 데이터 획득.그리고 우리는 NextJS
을 가지고 있다. 내가 보기에 이것은 현재ReactJS 웹 응용 프로그램을 작성하는 가장 좋은 방식이다. 서버 쪽에서 보여주고 클라이언트를 선택할 수 있다. 멋진 내장 루트, 0 설정 이념이다. NextJS9로 인해 이 프레임워크는 API 루트를 제공했다. 이것은 매우 간단한 방식이고 우리의ReactJS 응용 프로그램에 백엔드를 제공할 수 있다. 우리는 본고에서 사용할 것이다.본고에서 우리는 API 루트에서 실행되는 GraphQL API를 어떻게 실현하는지 배울 것이다.
기본 NextJS 응용 프로그램
앞서 언급한 바와 같이 NextJS가 주목하는 것은 0 설정 이념이다. 우리는 쉽게 설정할 수 있지만 더욱 간단하기 위해서 우리는 터미널에서 npx create-next-app todo-app
을 입력하면 사용할 수 있다.프로젝트 설정이 완료되면 cd todo-app
을 입력하고 yarn dev
을 입력하여 서버를 실행하고 모든 내용이 실행 중인지 확인합니다.
API 노선
차갑다우리는 현재nextjs 웹 프로그램을 시작하고 실행했습니다.pages/api/
에 graphql.js
이라는 새 파일을 만들고 다음 코드를 추가합니다.
export default (req, res) => {
res.statusCode = 200
res.send("GRAPHQL")
}
localhost:3000/api/graphql
으로 이동하면 작성된 텍스트 GRAPHQL을 볼 수 있습니다.쉬웠어이제 GraphQL을 구성합시다!
GraphQL 설정
설치
우선, 우리는 apollo-server-micro
을 작성하여 yarn add apollo-server-micro
이라는 의존항을 추가한다
우리 모드
다음에graphql 컴파일 모드를 사용해야 합니다. 이것은 우리의 조회와 돌연변이, 데이터의 구조를 정의합니다.현재 hello
이라는 검색을 원합니다. 문자열을 되돌려 줍니다.따라서 우리는 노선의 맨 위에 다음과 같은 내용을 추가합시다.
import { ApolloServer, gql } from 'apollo-server-micro'
const schema = gql`
type Query {
hello: String!
}
`;
해상도
우리는 방금 모드를 작성했지만, 현재 GraphQL은 모드 해상도가 필요합니다. 이것은 GraphQL이 데이터를 어디서 얻는지 알려 줍니다.모드 아래에 해석 프로그램을 추가합니다.
const resolvers = {
Query: {
hello: (_parent, _args, _context) => "world!"
}
}
서버
이제 모드와 해상도로 서버를 만듭니다.
const apolloServer = new ApolloServer({
typeDefs: schema,
resolvers,
context: () => {
return {}
}
})
멋지다. 이 실례를 통해 우리는 모든 요청과 응답을 처리하는 처리 프로그램에 접근할 수 있다. 왜냐하면 우리는 실제로NextJS를 사용하고 있기 때문이다. 우리는 그것을 지정해야 한다. 우리의 요청에는 bodyParser
이 필요하지 않다.
마지막 export default
을 삭제하고 다음 내용으로 변경합니다.
const handler = apolloServer.createHandler({ path: "/api/graphql" });
export const config = {
api: {
bodyParser: false
}
};
export default handler;
알겠습니다. 현재 GraphQL 서버의 기본 설정이 있습니다. 왜 localhost:3000/api/graphql
으로 넘어가지 않는지 확인하십시오!
하면, 만약, 만약...
query {
hello
}
우리는 해상도의 회답을 받을 것이다.
CORS 회사
우리는 이 API를 전방에서 사용하기 위해 다른 일이 필요합니다. 따라서 yarn add micro-cors
을 입력하여 새 패키지를 추가한 다음에 다음 내용을 추가합니다.
import Cors from "micro-cors";
const cors = Cors({
allowMethods: ["POST", "OPTIONS"]
});
// Here is how we connect our handler with cors.
export default cors(handler);
Knex의 Postgres를 사용한 데이터입니다.
어느 정도에, 우리의 응용 프로그램은 데이터베이스에 어떤 접근을 해야만 일부 데이터를 오래 저장할 수 있다.그러기 위해서는 뭔가를 설치해야 합니다. 시작합시다!우선 yarn add knex pg
으로 knex와 Postgres를 추가해 보도록 하겠습니다.
이제 데이터베이스 설정으로 knexfile.js
이라는 파일을 만듭니다.
module.exports = {
development: {
client: "postgresql",
connection: "postgres://postgres@localhost:5432/todo",
migrations: {
tableName: "knex_migrations"
}
},
};
다음은 첫 번째 마이그레이션을 만듭니다. Postgres에서 테이블을 만드는 방법을 알려 줍니다. yarn run knex migrate:make create_todo
을 입력하는 것부터 migrations
폴더에 새 파일을 생성합니다. 테이블을 열고 원하는 방식을 추가합니다.
exports.up = function(knex) {
return knex.schema.createTable("todos", function(table) {
table.increments("id");
table.string("description", 255).notNullable();
table.boolean("done").defaultTo(false).notNullable();
});
};
exports.down = function(knex) {
return knex.schema.dropTable("todos");
};
우리 책상 하나 만들자!yarn run knex migrate:up
실행
코드에서 데이터베이스를 관리하는 데 도움을 줄 상수를 만들어야 합니다./pages/api/graphql.js
을 열고 다음 내용을 추가합니다.
import knex from "knex";
const db = knex({
client: "pg",
connection: "postgres://postgres@localhost:5432/todo"
});
우리 모드 업데이트
쿨, 우리 이제 일할 수 있어.왜 우리는 패턴과 해상도를 바꾸지 않습니까?
const schema = gql`
type Query {
todos: [Todo]!
todo(id: ID!): Todo
}
type Todo {
id: ID!
description: String!
done: Boolean!
}
`;
const resolvers = {
Query: {
todos: (_parent, _args, _context) => {
return db
.select("*")
.from("todos")
.orderBy("id")
},
todo: (_parent, { id }, _context) => {
return db
.select("*")
.from("todos")
.where({ id })
.first()
}
}
}
만약 우리가 지금 localhost:3000/api/graphql
으로 돌아간다면, 우리는 최종적으로 우리의 데이터를 얻고 사용할 수 있을 것이다!
근데 잠깐만...우리는 어떻게 데이터를 만들 것입니까?
좋아요.Mutation
을 추가하는 방법을 보여 드리겠습니다. 이것은 데이터베이스에서 데이터를 만드는 데 도움을 줄 것입니다!
데이터 생성
우선, 우리는 모델에 새로운 유형을 추가해야 한다.이 예에서 우리는 먼저 돌연변이의 명칭 createTodo
을 지정한 다음에 괄호 안에서 우리가 받을 값의 명칭과 유형을 지정해야 한다. 마지막으로 우리는 돌연변이가 무엇을 되돌려줄지 지정해야 한다. 이 예에서 Todo
유형이다.
const schema = gql`
...
type Mutation {
createTodo(description: String!, done: Boolean): Todo
completeTodo(id: ID!): Todo
}
`;
현재 resolvers
대상에 새로운 Mutation
키와 createTodo
키를 추가합니다
const resolvers = {
...
Mutation: {
createTodo: async (_, { description, done }, _c) => {
return (await db("todos").insert({ description, done }).returning("*"))[0]
},
completeTodo: async (_, { id }, _c) => {
return (await db("todos").select("*").where({ id }).update({ done: true }).returning("*"))[0];
}
}
}
이제 데이터베이스에서 TODO를 만들고 완성할 수 있습니다.
멋있는데 앞머리는요?
고객
지금까지 우리는 API 루트에서graphql를 통합하여 응용 프로그램의 서버 쪽을 구축해 왔는데 왜 응용 프로그램의 클라이언트를 통합하지 않습니까?
의존항
우선 GraphQL에 연결하는 데 필요한 두 개의 의존 항목을 추가합니다.yarn add @apollo/react-hooks apollo-boost
공급업체
우선 응용 프로그램의 Apollo 클라이언트를 설정합니다.이를 위해 pages/_app.js
을 열고 다음을 추가합니다.
import '../styles/globals.css'
import { ApolloProvider } from '@apollo/react-hooks';
import ApolloClient, { gql } from 'apollo-boost';
function MyApp({ Component, pageProps }) {
const client = new ApolloClient({
uri: "http://localhost:3000/api/graphql"
})
return (
<ApolloProvider client={client}>
<Component {...pageProps} />
</ApolloProvider>
)
}
export default MyApp
조회
이제 pages/index.js
을 열고 필요한 내용을 가져오겠습니다.
import React, { useState } from 'react';
import { useQuery, useMutation } from "@apollo/react-hooks";
import { gql } from 'apollo-boost';
이제 GraphQL에서처럼 GraphQL 쿼리를 선언해야 합니다.
const GET_TODOS = gql`
query {
todos {
id
description
done
}
}
`
현재 우리 구성 요소에서, 우리는 조회와 맵을 사용하여 응용 프로그램에서 그것들을 렌더링할 것이다
export default function Home() {
const { loading, error, data, refetch } = useQuery(GET_TODOS);
if(loading) return <p>Loading...</p>
if(error) return <p>ERROR :(</p>
return (
<div>
<h1>My TODO list</h1>
{
data.todos.map((todo) => (
<div key={todo.id}>
{todo.description}
<button
disabled={todo.done}
>
{todo.done ? "Done" : "Complete"}
</button>
</div>
))
}
</div>
)
}
쿨, 이제 브라우저에서 우리가 해야 할 일을 볼 수 있을 거야.이제 TODO를 만드는 방법을 추가합니다.createTodo
돌연변이를 추가하는 것부터 시작하겠습니다.
const CREATE_TODO = gql`
mutation CreateTodo($description: String!) {
createTodo(description: $description) {
id
description
done
}
}
`
이제 구성 요소에 상태 관리, 변이 및 양식을 추가하여 변이를 수행합니다. 결과는 다음과 같습니다.
export default function Home() {
...
const [todo, setTodo] = useState("");
const [createTodo] = useMutation(CREATE_TODO);
const saveTodo = async (e) => {
e.preventDefault();
await createTodo({variables: { description: todo }});
refetch();
setTodo("")
}
...
return (
<div>
<h1>My TODO list</h1>
<form onSubmit={saveTodo}>
<label>
New todo
<input onChange={e => setTodo(e.target.value)} value={todo} />
</label>
<button type="submit">Save</button>
</form>
...
</div>
)
}
대기사항 완료
아주 간단해!,왜 우리는 completeTodo
의 변이를 추가하지 않고 단추에 기능을 추가합니까?
이것은 우리의 돌연변이 성명이다.
const COMPLETE_TODO = gql`
mutation CompleteTodo($id: ID!) {
completeTodo(id: $id) {
id
}
}
`
우리의 구성 요소 중에는 다음과 같은 것들이 있다.
export default function Home() {
const [todo, setTodo] = useState("");
const { loading, error, data, refetch } = useQuery(GET_TODOS);
const [createTodo] = useMutation(CREATE_TODO);
const [completeTodo] = useMutation(COMPLETE_TODO)
const saveTodo = async (e) => {
e.preventDefault();
await createTodo({variables: { description: todo }});
refetch();
setTodo("")
}
const onComplete = async (id) => {
await completeTodo({variables: { id }});
refetch();
}
if(loading) return <p>Loading...</p>
if(error) return <p>ERROR :(</p>
return (
<div>
<h1>My TODO list</h1>
<form onSubmit={saveTodo}>
<label>
New todo
<input onChange={e => setTodo(e.target.value)} value={todo} />
</label>
<button type="submit">Save</button>
</form>
{
data.todos.map((todo) => (
<div key={todo.id}>
{todo.description}
<button
disabled={todo.done}
onClick={() => onComplete(todo.id)}
>
{todo.done ? "Done" : "Complete"}
</button>
</div>
))
}
</div>
)
}
만약 지금 우리가 브라우저에 들어간다면, 우리는 우리의 응용 프로그램이 실행 중인 것을 볼 수 있습니다!
결론
GraphQL은 지난 몇 년 동안 끊임없이 발전해 온 기술이며, NextJS도 마찬가지다.현재, 우리는 우리의 NextJS 응용 프로그램에서 API 루트를 사용할 수 있다. 우리는 그것들을 통합하여 사람을 즐겁게 하는 창고를 구축할 수 있고, 완전한 창고 웹 응용 프로그램을 하나의 전체로 할 수 있지만, 심지어는 서버가 없는 응용 프로그램을 실행할 수 있다🤔?
사진은 Alina Grubnyak에서 Unsplash으로 촬영되었다
Reference
이 문제에 관하여(NextJS 및 Graphql이 포함된 풀스택 웹 응용 프로그램), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/gamezcua1/full-stack-web-app-with-nextjs-and-graphql-1dce
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
export default (req, res) => {
res.statusCode = 200
res.send("GRAPHQL")
}
import { ApolloServer, gql } from 'apollo-server-micro'
const schema = gql`
type Query {
hello: String!
}
`;
const resolvers = {
Query: {
hello: (_parent, _args, _context) => "world!"
}
}
const apolloServer = new ApolloServer({
typeDefs: schema,
resolvers,
context: () => {
return {}
}
})
const handler = apolloServer.createHandler({ path: "/api/graphql" });
export const config = {
api: {
bodyParser: false
}
};
export default handler;
query {
hello
}
import Cors from "micro-cors";
const cors = Cors({
allowMethods: ["POST", "OPTIONS"]
});
// Here is how we connect our handler with cors.
export default cors(handler);
module.exports = {
development: {
client: "postgresql",
connection: "postgres://postgres@localhost:5432/todo",
migrations: {
tableName: "knex_migrations"
}
},
};
exports.up = function(knex) {
return knex.schema.createTable("todos", function(table) {
table.increments("id");
table.string("description", 255).notNullable();
table.boolean("done").defaultTo(false).notNullable();
});
};
exports.down = function(knex) {
return knex.schema.dropTable("todos");
};
import knex from "knex";
const db = knex({
client: "pg",
connection: "postgres://postgres@localhost:5432/todo"
});
const schema = gql`
type Query {
todos: [Todo]!
todo(id: ID!): Todo
}
type Todo {
id: ID!
description: String!
done: Boolean!
}
`;
const resolvers = {
Query: {
todos: (_parent, _args, _context) => {
return db
.select("*")
.from("todos")
.orderBy("id")
},
todo: (_parent, { id }, _context) => {
return db
.select("*")
.from("todos")
.where({ id })
.first()
}
}
}
const schema = gql`
...
type Mutation {
createTodo(description: String!, done: Boolean): Todo
completeTodo(id: ID!): Todo
}
`;
const resolvers = {
...
Mutation: {
createTodo: async (_, { description, done }, _c) => {
return (await db("todos").insert({ description, done }).returning("*"))[0]
},
completeTodo: async (_, { id }, _c) => {
return (await db("todos").select("*").where({ id }).update({ done: true }).returning("*"))[0];
}
}
}
import '../styles/globals.css'
import { ApolloProvider } from '@apollo/react-hooks';
import ApolloClient, { gql } from 'apollo-boost';
function MyApp({ Component, pageProps }) {
const client = new ApolloClient({
uri: "http://localhost:3000/api/graphql"
})
return (
<ApolloProvider client={client}>
<Component {...pageProps} />
</ApolloProvider>
)
}
export default MyApp
import React, { useState } from 'react';
import { useQuery, useMutation } from "@apollo/react-hooks";
import { gql } from 'apollo-boost';
const GET_TODOS = gql`
query {
todos {
id
description
done
}
}
`
export default function Home() {
const { loading, error, data, refetch } = useQuery(GET_TODOS);
if(loading) return <p>Loading...</p>
if(error) return <p>ERROR :(</p>
return (
<div>
<h1>My TODO list</h1>
{
data.todos.map((todo) => (
<div key={todo.id}>
{todo.description}
<button
disabled={todo.done}
>
{todo.done ? "Done" : "Complete"}
</button>
</div>
))
}
</div>
)
}
const CREATE_TODO = gql`
mutation CreateTodo($description: String!) {
createTodo(description: $description) {
id
description
done
}
}
`
export default function Home() {
...
const [todo, setTodo] = useState("");
const [createTodo] = useMutation(CREATE_TODO);
const saveTodo = async (e) => {
e.preventDefault();
await createTodo({variables: { description: todo }});
refetch();
setTodo("")
}
...
return (
<div>
<h1>My TODO list</h1>
<form onSubmit={saveTodo}>
<label>
New todo
<input onChange={e => setTodo(e.target.value)} value={todo} />
</label>
<button type="submit">Save</button>
</form>
...
</div>
)
}
const COMPLETE_TODO = gql`
mutation CompleteTodo($id: ID!) {
completeTodo(id: $id) {
id
}
}
`
export default function Home() {
const [todo, setTodo] = useState("");
const { loading, error, data, refetch } = useQuery(GET_TODOS);
const [createTodo] = useMutation(CREATE_TODO);
const [completeTodo] = useMutation(COMPLETE_TODO)
const saveTodo = async (e) => {
e.preventDefault();
await createTodo({variables: { description: todo }});
refetch();
setTodo("")
}
const onComplete = async (id) => {
await completeTodo({variables: { id }});
refetch();
}
if(loading) return <p>Loading...</p>
if(error) return <p>ERROR :(</p>
return (
<div>
<h1>My TODO list</h1>
<form onSubmit={saveTodo}>
<label>
New todo
<input onChange={e => setTodo(e.target.value)} value={todo} />
</label>
<button type="submit">Save</button>
</form>
{
data.todos.map((todo) => (
<div key={todo.id}>
{todo.description}
<button
disabled={todo.done}
onClick={() => onComplete(todo.id)}
>
{todo.done ? "Done" : "Complete"}
</button>
</div>
))
}
</div>
)
}
Reference
이 문제에 관하여(NextJS 및 Graphql이 포함된 풀스택 웹 응용 프로그램), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/gamezcua1/full-stack-web-app-with-nextjs-and-graphql-1dce텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)