노드로 GraphQL API 구축

게시 됨: 2022-12-20

GraphQL은 API 개발의 새로운 유행어입니다. RESTful API는 애플리케이션에서 데이터를 노출하는 가장 인기 있는 방법으로 남아 있지만 GraphQL이 해결하고자 하는 많은 제한 사항이 있습니다.

GraphQL은 2015년에 오픈 소스 프로젝트로 전환된 Facebook에서 만든 쿼리 언어입니다. API에서 데이터를 설명하고 액세스하기 위한 직관적이고 유연한 구문을 제공합니다.

이 가이드에서는 GraphQL Node.js 프로젝트를 빌드하는 방법을 살펴봅니다. GraphQL을 사용하여 Node용 Express.js 웹 프레임워크에서 Todo 애플리케이션을 빌드합니다.

GraphQL이란 무엇입니까?

공식 문서에서: “GraphQL은 API용 쿼리 언어이자 기존 데이터로 이러한 쿼리를 수행하기 위한 런타임입니다. GraphQL은 API의 데이터에 대한 완전하고 이해하기 쉬운 설명을 제공하고, 고객에게 필요한 것을 정확히 요청할 수 있는 권한을 제공하며, 시간이 지남에 따라 API를 보다 쉽게 ​​발전시킬 수 있도록 하고, 강력한 개발자 도구를 지원합니다.”

GraphQL은 데이터에 대해 정의한 유형 시스템을 사용하여 쿼리를 실행하기 위한 서버 측 런타임입니다. 또한 GraphQL은 특정 데이터베이스 또는 스토리지 엔진에 연결되지 않습니다. 대신 기존 코드 및 데이터 저장소에서 지원합니다. GraphQL과 RESTful API 가이드를 통해 이러한 기술을 자세히 비교할 수 있습니다.

GraphQL 서비스를 만들려면 먼저 스키마 유형을 정의하고 해당 유형을 사용하여 필드를 만듭니다. 다음으로 클라이언트 측에서 데이터를 요청할 때마다 각 필드와 유형에서 실행할 함수 확인자를 제공합니다.

GraphQL 용어

GraphQL 유형 시스템은 쿼리할 수 있는 데이터와 조작할 수 있는 데이터를 설명하는 데 사용됩니다. GraphQL의 핵심입니다. GraphQ에서 데이터를 설명하고 조작할 수 있는 다양한 방법에 대해 논의해 봅시다.

유형

GraphQL 객체 유형은 강력한 유형의 필드를 포함하는 데이터 모델입니다. 모델과 GraphQL 유형 간에 일대일 매핑이 있어야 합니다. 다음은 GraphQL 유형의 예입니다.

 type User { id: ID! # The "!" means required firstname: String lastname: String email: String username: String todos: [Todo] # Todo is another GraphQL type }

쿼리

GraphQL 쿼리는 클라이언트가 GraphQL API에서 실행할 수 있는 모든 쿼리를 정의합니다. 규칙에 따라 모든 기존 쿼리를 포함할 RootQuery 를 정의해야 합니다.

아래에서 쿼리를 정의하고 해당 RESTful API에 매핑합니다.

 type RootQuery { user(id: ID): User # Corresponds to GET /api/users/:id users: [User] # Corresponds to GET /api/users todo(id: ID!): Todo # Corresponds to GET /api/todos/:id todos: [Todo] # Corresponds to GET /api/todos }

돌연변이

GraphQL 쿼리가 GET 요청인 경우 변형은 GraphQL API를 조작하는 POST , PUT , PATCHDELETE 요청입니다.

모든 돌연변이를 하나의 RootMutation 에 넣어 다음을 시연합니다.

 type RootMutation { createUser(input: UserInput!): User # Corresponds to POST /api/users updateUser(id: ID!, input: UserInput!): User # Corresponds to PATCH /api/users removeUser(id: ID!): User # Corresponds to DELETE /api/users createTodo(input: TodoInput!): Todo updateTodo(id: ID!, input: TodoInput!): Todo removeTodo(id: ID!): Todo }

UserInput , TodoInput 과 같은 변형에 대해 -input 유형을 사용하는 것을 확인했습니다. 리소스 생성 및 업데이트를 위한 입력 유형을 항상 정의하는 것이 항상 모범 사례입니다.

아래와 같이 입력 유형을 정의 수 있습니다.

 input UserInput { firstname: String! lastname: String email: String! username: String! }

리졸버

리졸버는 각 쿼리 또는 변형이 요청될 때 수행할 작업을 GraphQL에 알려줍니다. CRUD(생성, 읽기, 업데이트, 삭제) 작업을 수행하기 위해 데이터베이스 계층을 공격하거나, 내부 RESTful API 엔드포인트를 공격하거나, 클라이언트의 요청을 이행하기 위해 마이크로 서비스를 호출하는 힘든 작업을 수행하는 기본 기능입니다.

resolvers.js 파일을 만들고 다음 코드를 추가할 수 있습니다.

 import sequelize from '../models'; export default function resolvers () { const models = sequelize.models; return { // Resolvers for Queries RootQuery: { user (root, { id }, context) { return models.User.findById(id, context); }, users (root, args, context) { return models.User.findAll({}, context); } }, User: { todos (user) { return user.getTodos(); } }, } // Resolvers for Mutations RootMutation: { createUser (root, { input }, context) { return models.User.create(input, context); }, updateUser (root, { id, input }, context) { return models.User.update(input, { ...context, where: { id } }); }, removeUser (root, { id }, context) { return models.User.destroy(input, { ...context, where: { id } }); }, // ... Resolvers for Todos go here } }; }

개요

GraphQL 스키마는 GraphQL이 세계에 노출하는 것입니다. 따라서 유형, 쿼리 및 변이는 스키마 내부에 포함되어 세상에 노출됩니다.

다음은 유형, 쿼리 및 변형을 세계에 노출하는 방법입니다.

 schema { query: RootQuery mutation: RootMutation }

위의 스크립트에는 앞서 생성한 RootQueryRootMutation 을 세상에 노출시키기 위해 포함시켰습니다.

GraphQL은 Nodejs 및 Expressjs와 어떻게 작동합니까?

GraphQL은 모든 주요 프로그래밍 언어에 대한 구현을 제공하며 Node.js는 예외가 아닙니다. 공식 GraphQL 웹 사이트에는 JavaScript 지원에 대한 섹션이 있으며 GraphQL에서 작성 및 코딩을 간단하게 만드는 GraphQL의 다른 구현도 있습니다.

GraphQL Apollo는 Node.js 및 Express.js에 대한 구현을 제공하고 GraphQL을 쉽게 시작할 수 있도록 합니다.

다음 섹션에서 GraphQL Apollo를 사용하여 Nodes.js 및 Express.js 백엔드 프레임워크에서 첫 번째 GraphQL 애플리케이션을 만들고 개발하는 방법을 배웁니다.

Express.js로 GraphQL 설정하기

Express.js로 GraphQL API 서버를 구축하는 것은 간단하게 시작할 수 있습니다. 이 섹션에서는 GraphQL 서버를 구축하는 방법을 살펴보겠습니다.

Express로 프로젝트 초기화

먼저 새 Express.js 프로젝트를 설치하고 설정해야 합니다.

프로젝트용 폴더를 만들고 다음 명령을 사용하여 Express.js를 설치합니다.

 cd <project-name> && npm init -y npm install express

위의 명령은 새 package.json 파일을 만들고 Express.js 라이브러리를 프로젝트에 설치합니다.

다음으로 아래 이미지와 같이 프로젝트를 구성합니다. 사용자, 작업 등과 같은 프로젝트 기능에 대한 다양한 모듈이 포함됩니다.

graphql-todo의 파일 목록입니다.
graphql-todo 파일.

GraphQL 초기화

GraphQL Express.js 종속성을 설치하여 시작하겠습니다. 다음 명령을 실행하여 설치하십시오.

 npm install apollo-server-express graphql @graphql-tools/schema --save

스키마 및 유형 생성

다음으로 모듈 폴더 내에 index.js 파일을 만들고 다음 코드 스니펫을 추가합니다.

 const { gql } = require('apollo-server-express'); const users = require('./users'); const todos = require('./todos'); const { GraphQLScalarType } = require('graphql'); const { makeExecutableSchema } = require('@graphql-tools/schema'); const typeDefs = gql` scalar Time type Query { getVersion: String! } type Mutation { version: String! } `; const timeScalar = new GraphQLScalarType({ name: 'Time', description: 'Time custom scalar type', serialize: (value) => value, }); const resolvers = { Time: timeScalar, Query: { getVersion: () => `v1`, }, }; const schema = makeExecutableSchema({ typeDefs: [typeDefs, users.typeDefs, todos.typeDefs], resolvers: [resolvers, users.resolvers, todos.resolvers], }); module.exports = schema;

코드 연습

코드 스니펫을 통해 작업하고 분석해 보겠습니다.

1 단계

먼저 필요한 라이브러리를 가져오고 기본 쿼리 및 변형 유형을 생성했습니다. 쿼리 및 변형은 현재 GraphQL API의 버전만 설정합니다. 그러나 진행하면서 다른 스키마를 포함하도록 쿼리 및 변형을 확장할 것입니다.

GraphQL 및 기타 확장을 가져오기 위한 "const" 코드를 보여주는 명령줄 인터페이스.
GraphQL 및 확장 가져오기.
2 단계:

그런 다음 시간에 대한 새로운 스칼라 유형을 만들고 위에서 만든 쿼리 및 변형에 대한 첫 번째 리졸버를 만들었습니다. 또한 makeExecutableEchema 함수를 사용하여 스키마를 생성했습니다.

생성된 스키마에는 우리가 가져온 다른 모든 스키마가 포함되며 스키마를 만들고 가져올 때 더 많이 포함됩니다.

가동 중지 시간 및 WordPress 문제로 어려움을 겪고 있습니까? Kinsta는 시간을 절약하도록 설계된 호스팅 솔루션입니다! 우리의 기능을 확인하십시오
스칼라 유형과 첫 번째 리졸버를 생성하기 위한 "const" 코드를 보여주는 명령줄 인터페이스.
시간에 대한 스칼라 유형과 첫 번째 리졸버를 생성합니다.

위의 코드 스니펫은 다른 스키마를 makeExecutableEchema 함수로 가져왔음을 보여줍니다. 이 접근 방식은 애플리케이션의 복잡성을 구조화하는 데 도움이 됩니다. 다음으로 가져온 Todo 및 사용자 스키마를 생성합니다.

Todo 스키마 생성

Todo 스키마는 애플리케이션 사용자가 수행할 수 있는 간단한 CRUD 작업을 보여줍니다. 아래는 Todo CRUD 작업을 구현한 스키마입니다.

 const { gql } = require('apollo-server-express'); const createTodo = require('./mutations/create-todo'); const updateTodo = require('./mutations/update-todo'); const removeTodo = require('./mutations/delete-todo'); const todo = require('./queries/todo'); const todos = require('./queries/todos'); const typeDefs = gql` type Todo { id: ID! title: String description: String user: User } input CreateTodoInput { title: String! description: String isCompleted: Boolean } input UpdateTodoInput { title: String description: String isCompleted: Boolean } extend type Query { todo(id: ID): Todo! todos: [Todo!] } extend type Mutation { createTodo(input: CreateTodoInput!): Todo updateTodo(id: ID!, input: UpdateTodoInput!): Todo removeTodo(id: ID!): Todo } `; // Provide resolver functions for your schema fields const resolvers = { // Resolvers for Queries Query: { todo, todos, }, // Resolvers for Mutations Mutation: { createTodo, updateTodo, removeTodo, }, }; module.exports = { typeDefs, resolvers };

코드 연습

코드 스니펫을 통해 작업하고 분석해 보겠습니다.

1 단계:

먼저 GraphQL type , inputextend 를 사용하여 Todo에 대한 스키마를 생성했습니다. extend 키워드는 위에서 만든 기존 루트 쿼리 및 변형에 새 쿼리 및 변형을 상속하고 추가하는 데 사용됩니다.

새 입력을 포함하여 Todo 스크립트의 스키마를 보여주는 명령줄 인터페이스.
Todo에 대한 스키마 생성.
2 단계:

다음으로 특정 쿼리 또는 변형이 호출될 때 올바른 데이터를 검색하는 데 사용되는 확인자를 만들었습니다.

Todo에 대한 리졸버를 생성하는 코드를 보여주는 명령줄 인터페이스.
리졸버 생성.

리졸버 기능을 사용하면 create-todo.js 예제와 같이 비즈니스 로직 및 데이터베이스 조작을 위한 개별 메서드를 생성할 수 있습니다.

<code>./mutations</code> 폴더에 create-user.js 파일을 만들고 비즈니스 로직을 추가하여 데이터베이스에 새 Todo를 만듭니다.

 const models = require('../../../models'); module.exports = async (root, { input }, context) => { return models.todos.push({ ...input }); };

위의 코드 스니펫은 Sequelize ORM을 사용하여 데이터베이스에서 새 Todo를 만드는 간단한 방법입니다. Sequelize 및 Node.js로 설정하는 방법에 대해 자세히 알아볼 수 있습니다.

동일한 단계를 따라 애플리케이션에 따라 많은 스키마를 생성하거나 GitHub에서 전체 프로젝트를 복제할 수 있습니다.

다음으로 Express.js로 서버를 설정하고 새로 생성된 Todo 애플리케이션을 GraphQL 및 Node.js로 실행합니다.

서버 설정 및 실행

마지막으로 앞서 설치한 apollo-server-express 라이브러리를 사용하여 서버를 설정하고 구성합니다.

apollo-server-express 는 Express.js용 Apollo Server의 단순 래퍼로, Express.js 개발에 맞게 개발되었기 때문에 권장됩니다.

위에서 설명한 예제를 사용하여 새로 설치된 apollo-server-express 와 함께 작동하도록 Express.js 서버를 구성해 보겠습니다.

루트 디렉터리에 server.js 파일을 만들고 다음 코드를 붙여넣습니다.

 const express = require('express'); const { ApolloServer } = require('apollo-server-express'); const schema = require('./modules'); const app = express(); async function startServer() { const server = new ApolloServer({ schema }); await server.start(); server.applyMiddleware({ app }); } startServer(); app.listen({ port: 3000 }, () => console.log(`Server ready at http://localhost:3000`) );

위의 코드에서 Todos 및 사용자를 위한 첫 번째 CRUD GraphQL 서버를 성공적으로 생성했습니다. http://localhost:3000/graphql을 사용하여 개발 서버를 시작하고 플레이그라운드에 액세스할 수 있습니다. 모든 것이 성공하면 아래 화면이 표시됩니다.

응답으로 간단한 쿼리를 보여주는 개발 인터페이스.
확인 화면입니다.

요약

GraphQL은 RESTful 아키텍처 패턴으로 대규모 API 생성과 관련된 지루한 작업을 단순화하는 Facebook에서 지원하는 최신 기술입니다.

이 가이드는 GraphQL을 설명하고 Express.js로 첫 번째 GraphQL API를 개발하는 방법을 시연했습니다.

GraphQL을 사용하여 무엇을 빌드하는지 알려주세요.