Skip to content

Jeontaeyun/personal-blog-graphql

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

38 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Personal Branding Blog Backend with GraphQL

Goal of Project

I am going to make some blog project with Typescript, GraphQL(Apollo-Client) and Next.js. The purpose of this project is that,

  1. Studying and Using Typescript

  2. Learn GraphQL and Get the gist of difference between GraphQL and REST API.

  3. Get the experience with design -> develope -> deploy

Project Setting

Directory Structure | 3 Layer Architecture

This architecture from Bulletproof node.js project architecture ๐Ÿ›ก๏ธ written by Sam Quinn

Directory Description
app.ts App entry point
api Express route controllers for all the endpoints of the app
graphql Apollo-GraphQL Resolver
config Environment variables and configuration related stuff
jobs Jobs definitions for agenda.js (Scheduler modules)
loaders Split the startup process into modules
models Database models
services All the business logic is here
subscribers Event handlers for async task
types Type declaration files (d.ts) for Typescript

I'm going to apply "The principle of separation of concerns" with Controller - Service Layer - Data Access Layer (3 Layer Architecture).

Project Init

$mkdir <serverName>
$cd <serverName>
$touch index.js or index.tsx
$npm init -y

Install Apollo Server

 $npm i apollo-server graphql
  • apollo-serve๋Š” Apollo์—์„œ ์ œ๊ณตํ•˜๋Š” GaphQL ์„œ๋ฒ„ ํŒจํ‚ค์ง€์ž…๋‹ˆ๋‹ค.
  • graphql์€ Facebook์—์„œ ์ •์˜ํ•œ GraphQL ์ŠคํŽ™์„ JS์–ธ์–ด๋กœ ๊ตฌํ˜„ํ•œ ํŒจํ‚ค์ง€์ž…๋‹ˆ๋‹ค.

Apollo-server and Apollo-Client depends on graphql package, so you're supposed to install this package together.

Basic Server Code | Index.ts

First of all, We write index.ts for using Apollo-Server.

const { ApolloServer, gql } = require("apollo-server");
  • ApolloServer๋Š” GraphQL ์„œ๋ฒ„ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์ƒ์„ฑ์ž์ž…๋‹ˆ๋‹ค.
  • gql์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ GraphQL ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด ํƒœ๊ทธ์ž…๋‹ˆ๋‹ค.

๊ทธ ํ›„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

const typeDefs = gql`
    type Query {
        ping : String
    }
`;

const resolvers = {
    Query: {
        ping() => "pong"
    }
};
  • typeDefs ๋ณ€์ˆ˜๋Š” gql์„ ์ด์šฉํ•ด GraphQL ์Šคํ‚ค๋งˆ ํƒ€์ž…์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  • resolvers ๋ณ€์ˆ˜๋Š” GraphQL ์Šคํ‚ค๋งˆ๋ฅผ ํ†ตํ•ด ์ œ๊ณตํ•  ๋ฐ์ดํ„ฐ๋ฅผ ์ •์˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋‹ด์€ ๊ฐ์ฒด๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.
  • ์œ„๋Š” String ๋ฐ์ดํ„ฐ์— ์‘๋‹ตํ•  ์ˆ˜ ์žˆ๋Š” ping์ด๋ผ๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ •์˜ํ•œ ํ›„, ping์ด๋ผ๋Š” ์ฟผ๋ฆฌ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ํ•ญ์ƒ pong์ด๋ผ๋Š” ๋ฌธ์ž์—ด์„ ์‘๋‹ตํ•˜๋„๋ก ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

const server = new ApolloServer({
    typeDefs,
    resolvers
});

server.listen().then(({ url }) => {
    console.log(`Listening at ${url}`);
});
  • ์œ„ ์ฝ”๋“œ๋Š” typeDefs์™€ resolvers๋ฅผ ApolloServer ์ƒ์„ฑ์ž์— ๋„˜๊ฒจ GraphQL ์„œ๋ฒ„ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ทธ ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•ด์ฃผ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

Run Server

When run Apollo-Server with below command, You can see "Apollo Server ready at http/graphql"

$node .
$node index.js

Server Test

์ฝ˜์†”์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„œ๋ฒ„์˜ ์‘๋‹ต ๊ฒฐ๊ณผ๋ฅผ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$curl -X POST "http;//localhost:4000" -H "content-type: application/json" -d '{"query":"{ping}"}'
  • curl์€ ๋‹ค์–‘ํ•œ ํ”„๋กœํ† ์ฝœ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ๋ช…๋ น์ค„ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.
    • ์›๊ฒฉ ์„œ๋ฒ„(FTP, HTTP๋“ฑ)์—์„œ ํŒŒ์ผ์„ ๋ฐ›์•„ ๋ณด์—ฌ์ฃผ๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.
  • ๋˜ํ•œ Graph QL ์„œ๋ฒ„๋Š” Playground๋ผ๊ณ  ํ•˜๋Š” ์›น ๊ธฐ๋ฐ˜ ํˆด์ด ์žˆ์–ด์„œ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋„ ์ฟผ๋ฆฌ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Express Setting

 $npm i apollo-server-express
 $npm i express

๊ทธ ํ›„ index.js ํŒŒ์ผ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

import expess = require('express');
import { ApolloServer } = require('apollo-server-express');

const app = express();
...
const server = new ApolloServer({
    typeDefs,
    resolvers
});

server.applyMiddleware({app, path: '/graphql'});

app.listen({port: 8000}, ()=> {
    console.log('Apollo Server on http://localhost:8000/graphql');
});

CORS ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด CORS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ต์Šคํ”„๋ ˆ์Šค์— ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค.

$npm i cors
import cors = require('cors');
import expess = require('express');
import { ApolloServer } = require('apollo-server-express');

const app = express();
app.use(cors());

...

MySQL๊ณผ Sequelize ์„ค์ •

$npm i mysql2 sequelize
$npm i nodemon -dev
$npm i sequelize-cli -g

๊ทธ ํ›„ ๋‹ค์Œ sequelize-cli๋ฅผ ์ด์šฉํ•ด sequelize๋ฅผ ์ดˆ๊ธฐํ™” ํ•ฉ๋‹ˆ๋‹ค.

$sequelize init

์ด๋Ÿฌ๋ฉด config, models, migration, seeders๋ผ๋Š” ํด๋”๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
modelํด๋” ์•ˆ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ์Šคํ‚ค๋งˆ๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ posts ํ…Œ์ด๋ธ”์— ๋Œ€ํ•ด ๊ธฐ์ˆ ํ•œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.

module.exports = (sequelize, DataTypes) => {
    // TABLE NAME : posts
    const Post = sequelize.define(
        "Post",
        {
            title: {
                type: DataTypes.STRING(20),
                allowNull: false
            },
            description: {
                type: DataTypes.TEXT,
                allowNull: false
            }
        },
        {
            charset: "utf8",
            collate: "utf8_general_ci",
            tableName: "posts"
        }
    );
    Post.associate = db => {
        db.Post.belongsTo(db.User);
        db.Post.hasMany(db.Comment);
        db.Post.hasMany(db.Image);
        db.Post.belongsToMany(db.Tag, { through: "PostTag" });
        db.Post.belongsToMany(db.User, { through: "Like", as: "Liker" });
    };
    return Post;
};

ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐ Index.js ์„ค์ •

const express = require("express");
const cors = require("cors");
const cookieParser = require("cookie-parser");
const expressSession = require("express-session");

const { ApolloServer, gql } = require("apollo-server-express");
const typeDefs = require("./graphql/schema");
const resolvers = require("./graphql/resolvers");

const db = require("./models");

const dotenv = require("dotenv");
const morgan = require("morgan");

// Express App Init
const app = express();
dotenv.config();

// Apollo Server Init
const server = new ApolloServer({
    typeDefs: gql(typeDefs),
    resolvers,
    context: { db }
});

// Express Environment Setting
app.use(morgan("dev"));
app.use(express.json());
// JSONํ˜•ํƒœ์˜ ๋ณธ๋ฌธ์„ ์ฒ˜๋ฆฌํ•˜๋Š” express ๋ฏธ๋“ค์›จ์–ด
app.use(express.urlencoded({ extended: true }));
// FORM์„ ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” express ๋ฏธ๋“ค์›จ์–ด
app.use(
    cors({
        origin: true,
        credentials: true
    })
);
app.use("/", express.static("public"));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(
    expressSession({
        resave: false,
        saveUninitialized: false,
        secret: process.env.COOKIE_SECRET,
        cookie: {
            httpOnly: true,
            secure: false
        },
        name: "..."
    })
);

//Database Init
db.sequelize.sync();

// Express API
server.applyMiddleware({ app, path: "/graphql" });

//Starting Express App
app.listen({ port: 8000 }, () => {
    console.log("Apollo Server on ...");
});

JEST์™€ apollo-server-testing ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์ •

apollo-server-testing ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ JEST๋ฅผ ์ด์šฉํ•ด Apollo-Server๋ฅผ ํ…Œ์ŠคํŠธ ํ•˜๋Š” ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๋จผ์ €, GraphQL์˜ typeDefs์™€ schema๋ฅผ ๋„ฃ์€ testServer๋ฅผ ์ƒ์„ฑ

const { ApolloServer } = require("apollo-server");
const graphqlConfig = require("../graphql");
const db = require("../models");
const baseContext = {
    req: {
        user: null,
        login: (user, cb) => {
            this.user = user;
            baseContext.user = user;
            cb();
        },
        logout: () => {
            baseContext.user = null;
            this.user = null;
        }
    },
    db,
    user: null
};

module.exports = {
    testServer: new ApolloServer({
        ...graphqlConfig,
        context: baseContext
    }),
    baseContext
};

context์— express์™€ ์—ฐ๋™๋œ ๋ถ€๋ถ„์„ ๋„ฃ๋Š” ๊ฒƒ ๋ณด๋‹จ Mock์„ ๊ตฌํ˜„ํ•ด๋ณผ ๊ฒธ passport.js ๊ธฐ๋Šฅ๊ณผ req๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ basecontext์— ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค.
์ด ํ›„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด testClient๋ฅผ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค.

const { testServer } = require("./mockTestServer");
const { gql } = require("apollo-server-express");
const { createTestClient } = require("apollo-server-testing");
const dotenv = require("dotenv");
dotenv.config();

const { query, mutate } = createTestClient(testServer);

์œ„์—์„œ ์ƒ์„ฑ ๋œ query์™€ mutate์™€ JEST์˜ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด Apollo-Server๋ฅผ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

describe('ํ…Œ์ŠคํŠธ ๊ทธ๋ฃน ๋‹จ์œ„', () => {
it('์œ ์ €๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ…Œ์ŠคํŠธ', async () => {
	const CREATE_USER = gql`
		mutation($userId: String!, $password: String!, $grant: Int!, $nickname: String!) {
			createUser(userId: $userId, password: $password, grant: $grant, nickname: $nickname) {
				id
				userId
				nickname
				grant
			}
		}
	`;
	const { data: { createUser } } = await mutate({
		mutation: CREATE_USER,
		variables: testUser
	});
	const { userId, grant, nickname } = testUser;
	testUser['id'] = createUser.id;
	expect(createUser).toEqual({ id: createUser.id, userId, grant, nickname });
});
...

Reviewing of Project

01. Graph QL์˜ ์‚ฌ์šฉ

2019๋…„๋„ ์›น ๊ฐœ๋ฐœ ํŠธ๋ Œ๋“œ์ธ Graph QL์„ ์„œ๋ฒ„์ธก๊ณผ ํด๋ผ์ด์–ธํŠธ ์ธก ๋ชจ๋‘์—์„œ ์‚ฌ์šฉํ•ด ๋ณด์•˜๋‹ค.
์ด๋ฅผ ์‚ฌ์šฉํ•ด ๋ณธ ํ›„ ๋А๋‚€์ ์€ GraphQL์ด ๋‹ค์–‘ํ•œ ํ”Œ๋žซํผ๊ณผ ๋‹ค์–‘ํ•œ ์„œ๋ฒ„ ํ™˜๊ฒฝ์—์„œ์˜ ๋ฐ์ดํ„ฐ ํ†ต์‹ ์„ ์ง€์›ํ•˜๋ฉฐ API ํ˜ธ์ถœ๊ฐ„ ๋ถˆํ•„์š” ํ•œ ์˜ค๋ฒ„ ํŒจ์น˜์™€ ์–ธ๋” ํŒจ์น˜๋ฅผ ๋ฐฉ์ง€ํ•ด์ฃผ๋Š” ์œ ์šฉํ•œ ๊ธฐ์ˆ  ์Šคํƒ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ์•˜๋‹ค.

์ผ๋‹จ ๊ทธ๋ž˜ํ”„ ํ์—˜์˜ ํฐ ์žฅ์  ๋ฐ ํŠน์ง•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ง‘์•ฝํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ๋ ˆ๊ฑฐ์‹œ API, ํŒŒ์ผ ์‹œ์Šคํ…œ ๋“ฑ ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋‹ค์–‘ํ•œ ํ”Œ๋žซํผ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค. ๋ชจ๋ฐ”์ผ(IOS, Android), ์›น, IOT ์ „์ž๊ธฐ๊ธฐ ๋“ฑ ๋‹ค์–‘ํ•œ ํ”Œ๋žซํผ์— ๋Œ€์‘ ๊ฐ€๋Šฅํ•˜๋‹ค
  • ๋ฐ์ดํ„ฐ๋ฅผ ์งˆ์˜์–ด ํ˜•์‹์œผ๋กœ ๊ตํ™˜ํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ์–ธ๋” ํŒจ์น˜์™€ ์˜ค๋ฒ„ ํŒจ์น˜๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค๋งŒ, GraphQL์„ ํ†ตํ•œ ์ธ์ฆ(Authentication) ๋“ฑ ๊ธฐํƒ€ ๋ช‡๋ช‡ ๋ถ€๋ถ„์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ํ•˜๋‚˜์˜ ๊ธฐ์ˆ  ์Šคํƒ์œผ๋กœ ์ƒ๊ฐํ•˜๊ณ  ๊ธฐ์กด์˜ REST API์™€ ๊ฐ™์ด ํ˜ผํ•ฉํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐฑ์—”๋“œ์™€ ํ”„๋ก ํŠธ์—”๋“œ๊ฐ„์˜ ์ž‘์—… ํšจ์œจ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ณ  ๋‹ค์–‘ํ•œ ํ”Œ๋žซํผ์— ์†์‰ฝ๊ฒŒ ์ ์šฉํ•  ์†”๋ฃจ์…˜์ผ ๊ฒƒ์ด๋ผ ์ƒ๊ฐํ•œ๋‹ค.

02. JEST์™€ ํ…Œ์ŠคํŠธ

ํ•ด๋‹น ํ”„๋กœ์ ํŠธ์—์„œ Server๋ฅผ ๋งŒ๋“ค๊ณ  ํ…Œ์ŠคํŠธ ํ•  ๋•Œ๋งˆ๋‹ค ๋กœ๊ทธ์ธ ํ•˜๊ณ , Graph QL ์ฟผ๋ฆฌ๋ฅผ ํ”Œ๋ ˆ์ด ๊ทธ๋ผ์šด๋“œ์—์„œ ์ง์ ‘ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋ฒˆ๊ฑฐ๋กœ์›€์„ ๋А๊ผˆ๋‹ค.
์ด๋Ÿฐ ๋ถˆํŽธํ•จ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Apollo-Server๋ฅผ ํ…Œ์ŠคํŒ…ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋ณด์•˜๊ณ  2019๋…„ ํ…Œ์ŠคํŒ… ํ”„๋ ˆ์ž„์›คํฌ๋กœ ํ™”๋‘๊ฐ€ ๋˜๊ณ ์žˆ๋Š” JEST๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ธฐ๋กœํ–ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ…Œ์ŠคํŠธ์— ๋Œ€ํ•œ 3๊ฐ€์ง€ ํŠน์„ฑ์„ ์•Œ์•˜๋‹ค.

  • ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์—๋„ ๋ฐ˜๋“œ์‹œ ์‹œ๊ฐ„(๋น„์šฉ)์ด ์†Œ๋ชจ๋œ๋‹ค.
  • ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ(Integration Testing)์€ ์ „์ฒด ๊ธฐ๋Šฅ์„ ๋น ๋ฅด๊ฒŒ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์—ฐ๊ฒฐ์ด ๋งŽ์€ ๋งŒํผ ์ž‘์„ฑ์„ ๋งค๋„๋Ÿฝ๊ฒŒ ํ•˜๊ธฐ ์–ด๋ ต๋‹ค.
  • ๋‹จ์œ„ ํ…Œ์ŠคํŠธ(Unit Testing)์€ ๋‹ค๋ฅธ ์—ฐ๊ฒฐ๊ณผ์˜ ๋ฌธ์ œ๋กœ ํ…Œ์ŠคํŠธ๊ฐ€ ์–ด๋ ค์šธ ๋•Œ Mocking์ด ํ•„์š”ํ•˜๋‹ค.

ํ…Œ์ŠคํŠธ์— ๋Œ€ํ•œ ์œ„์˜ ํŠน์„ฑ์„ ํ†ตํ•ด ๋‚˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ…Œ์ŠคํŠธ์˜ ์žฅ๋‹จ์ ์— ๋Œ€ํ•ด ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค.

๊ตฌ๋ถ„ ์„ค๋ช…
์žฅ์  - ์ž‘์„ฑ๋œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ๋œ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผํ•  ๋•Œ ๋ฐ˜๋ณต๋œ ํ…Œ์ŠคํŠธ ์ ˆ์ž๋ฅผ ์ž๋™ํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค.(๋น„์šฉ์ ˆ๊ฐ)
- ํ•„์š”ํ•œ ๋™์ž‘์— ๋Œ€ํ•œ ๊ธฐ๋Šฅ ์žฌ์ •์˜ ๋ฐ ์•ˆ์ •์ ์ธ ์ฝ”๋“œ ์ž‘์„ฑ(์•ˆ์ •์„ฑ)
๋‹จ์  - ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์†Œ๋ชจ๋˜๋Š” ์‹œ๊ฐ„์ด ๋งŽ๋‹ค.(์ƒ์‚ฐ์„ฑ ํ•˜๋ฝ)
- ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ํ…Œ์ŠคํŠธ ํ•˜๊ธฐ ์œ„ํ•œ ๋ณต์žกํ•œ ๊ณผ์ •์ด ์ƒ๊ธด๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ํ…Œ์ŠคํŠธ์˜ ํ•„์š”์„ฑ์„ ๋А๊ผˆ์ง€๋งŒ, ์ƒํ™ฉ์— ๋”ฐ๋ผ ํ…Œ์ŠคํŠธ๋ฅผ ๋„์ž…ํ•  ์ง€ ๋ง์ง€์— ๋Œ€ํ•œ ์ƒ๊ฐ์„ ํ•˜๊ฒŒ๋˜์—ˆ๋‹ค.

03. GraphQL Codegen

GraphQL Codegen is the paser which is translate between schema.graphql and native language. We can get some types for tpyescript to use graphql-codegen.

$yarn add -D @graphql-codegen/cli
$yarn add -D @graphql-codegen/typescript

And we need to write some script code like this.

{
    "scripts": {
        "codegen:start": "graphql-codegen graphql-codegen --config codegen.yml",
        "codegen:init": "graphql-codegen init"
    }
}

Also, we need configuration for graphql-codegne codegen.yml

overwrite: true
schema: "./graphql/schema/schema.graphql"
documents: null
generates:
    src/types/graphql.ts:
       config:
       contextType: ../context                    #MyContext
       plugins:
            - "typescript"
            - "typescript-resolvers"

About

Personal blog project with Typescript, Apollo-Server, Express, GraphQL

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors