GraphQL+Mongodb.간단한 방법.

편집: 이 글의 반응을 보고 Prisma를 사용하여 새로운 GraphQL 기능을 업데이트하고 사용하고 싶은 데이터베이스에 사용할 것입니다.고마워, 알바로.
얘 여기 있어!새 버전:
안녕하세요!저는 알바로라고 합니다. 이것은 제가 여기 있는 첫 번째 댓글입니다.나는 줄곧 다른 사이트에서 글을 썼다. 예를 들면medium이다.
하지만!지금 나는 여기에 있다. 나는 여기에 한동안 머물고 싶다.
지난 몇 달 동안 GraphQL을 해 왔는데 정말 좋아해요.
오늘 우리는 공부할 것이다.
  • GraphQL 서버 설정 방법
  • 이 API 조회 방법
  • 몬고
  • 에 연결
    응용 프로그램에서 우리는 인증을 받은 사용자를 가질 것입니다. 이렇게 해야만 댓글을 만들 수 있습니다.
    우리 시작합시다!

    1、babel로 노드 설정


    mkdir graphql-test && cd graphql-test
    yarn init -y
    yarn add --dev nodemon @babel/core @babel/node @babel/preset-env
    
    나는 실을 사용하지만, 너는 npm를 사용할 수 있다. 
    만들다.루트 디렉토리에 LRC 파일을 만들고 이 구성을 pase합니다.
    {
      "presets": ["@babel/preset-env"]
    }
    
    

    2. 파일 및 디렉토리 조직 만들기

  • 루트 디렉터리에서 폴더 src
  • 만들기
  • src 내부: 모델, 모델, 해상도
  • 현재, src에서 색인을 만듭니다.js
  • 우리가 사용할 모든 패키지를 설치합니다.
  • yarn add mongoose jsonwebtoken bcrypt express graphql cors apollo-server apollo-server-express
    
  • 패키지에 스크립트를 만듭니다.서버를 시작하는 json:
  • {
      "name": "graphql-test",
      "version": "1.0.0",
      "main": "index.js",
      "license": "MIT",
      "scripts": {
        "dev": "nodemon --exec babel-node src/index.js"
      },
      "devDependencies": {
        "@babel/core": "^7.4.5",
        "@babel/node": "^7.4.5",
        "@babel/preset-env": "^7.4.5",
        "apollo-server": "^2.6.1",
        "apollo-server-express": "^2.6.1",
        "bcrypt": "^3.0.6",
        "cors": "^2.8.5",
        "express": "^4.17.1",
        "graphql": "^14.3.1",
        "jsonwebtoken": "^8.5.1",
        "mongoose": "^5.5.12",
        "nodemon": "^1.19.1"
      }
    }
    
    
    색인에 있습니다.js는 모든 것이 시작되는 곳이다.

    3. 몬고 모형 만들기


    GraphQL에 집중하고 싶다면 모든 몬고의 속도를 높여야 합니다.
    모델 내부에서 userModel 및 postModel 만들기:
    모델 후.회사 명
    import mongoose from 'mongoose';
    
    const postSchema = new mongoose.Schema({
      title: {
        type: String,
        required: true,
      },
      content: {
        type: String,
        required: true,
      },
      author: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'user',
      },
    });
    
    const post = mongoose.model('post', postSchema);
    
    export default post;
    
    사용자 모델.회사 명
    import bcrypt from 'bcrypt';
    import mongoose from 'mongoose';
    
    const userSchema = new mongoose.Schema({
      name: {
        type: String,
        required: true,
        unique: true,
      },
      password: {
        type: String,
        required: true,
      },
      posts: [
        {
          type: mongoose.Schema.Types.ObjectId,
          ref: 'post',
        },
      ],
    });
    
    userSchema.pre('save', function() {
      const hashedPassword = bcrypt.hashSync(this.password, 12);
      this.password = hashedPassword;
    });
    
    const user = mongoose.model('user', userSchema);
    
    export default user;
    

    4. 우리 모드 만들기


    /src/schema에서 postSchema를 만듭니다.js와 userSchema.회사 명
    import { gql } from 'apollo-server';
    
    export default gql`
      type Post {
        id: ID!
        title: String!
        content: String!
        author: User!
      }
    
      extend type Query {
        post(id: ID!): Post!
        posts: [Post!]!
      }
    
      extend type Mutation {
        createPost(title: String!, content: String!): Post!
      }
    `;
    
    import { gql } from 'apollo-server';
    
    export default gql`
      type User {
        id: ID!
        name: String!
        posts: [Post!]!
      }
    
      type Token {
        token: String!
      }
    
      extend type Query {
        user(id: ID!): User!
        login(name: String!, password: String!): Token!
      }
    
      extend type Mutation {
        createUser(name: String!, password: String!): User!
      }
    `;
    
  • 우리는 extend Anotion을 사용합니다. 왜냐하면 우리는 우리가 함께 추가한 모든 모델을 사용하는 링크 모드를 만들 것입니다.우리는 단지 하나의 검색 형식만 있을 수 있기 때문에 확장은 이 두 가지 유형을 동시에 사용할 수 있고 돌연변이와 구독에도 적용된다.
  • 사용자 중 암호를 추가하지 않았기 때문에 클라이언트가 암호를 조회할 수 없습니다.
  • 이것은 우리의 링크 모드입니다.
    import userSchema from './user';
    import postSchema from './post';
    import { gql } from 'apollo-server';
    
    const linkSchema = gql`
      type Query {
        _: Boolean
      }
      type Mutation {
        _: Boolean
      }
    `;
    
    export default [linkSchema, userSchema, postSchema];
    
    
    모드/인덱스에서 만들었습니다.js, 이것은 우리가 잠시 후에 색인에서 가져올 모드입니다.

    5. 우리의 해상도를 만듭니다


    패턴과 마찬가지로, 우리는 후분해기를 만들었다.js 및 userResolverssrc/resolvers의 js
    import { AuthenticationError } from 'apollo-server';
    
    export default {
      Query: {
        post: async (parent, { id }, { models: { postModel }, me }, info) => {
          if (!me) {
            throw new AuthenticationError('You are not authenticated');
          }
          const post = await postModel.findById({ _id: id }).exec();
          return post;
        },
        posts: async (parent, args, { models: { postModel }, me }, info) => {
          if (!me) {
            throw new AuthenticationError('You are not authenticated');
          }
          const posts = await postModel.find({ author: me.id }).exec();
          return posts;
        },
      },
      Mutation: {
        createPost: async (parent, { title, content }, { models: { postModel }, me }, info) => {
          if (!me) {
            throw new AuthenticationError('You are not authenticated');
          }
          const post = await postModel.create({ title, content, author: me.id });
          return post;
        },
      },
      Post: {
        author: async ({ author }, args, { models: { userModel } }, info) => {
          const user = await userModel.findById({ _id: author }).exec();
          return user;
        },
      },
    };
    
    import bcrypt from 'bcrypt';
    import jwt from 'jsonwebtoken';
    import { AuthenticationError } from 'apollo-server';
    
    export default {
      Query: {
        user: async (parent, { id }, { models: { userModel }, me }, info) => {
          if (!me) {
            throw new AuthenticationError('You are not authenticated');
          }
          const user = await userModel.findById({ _id: id }).exec();
          return user;
        },
        login: async (parent, { name, password }, { models: { userModel } }, info) => {
          const user = await userModel.findOne({ name }).exec();
    
          if (!user) {
            throw new AuthenticationError('Invalid credentials');
          }
    
          const matchPasswords = bcrypt.compareSync(password, user.password);
    
          if (!matchPasswords) {
            throw new AuthenticationError('Invalid credentials');
          }
    
          const token = jwt.sign({ id: user.id }, 'riddlemethis', { expiresIn: 24 * 10 * 50 });
    
          return {
            token,
          };
        },
      },
      Mutation: {
        createUser: async (parent, { name, password }, { models: { userModel } }, info) => {
          const user = await userModel.create({ name, password });
          return user;
        },
      },
      User: {
        posts: async ({ id }, args, { models: { postModel } }, info) => {
          const posts = await postModel.find({ author: id }).exec();
          return posts;
        },
      },
    };
    
  • 조회는 형식 조회에서 우리가 모드에서 만든 모든'함수'를 해석합니다.
  • 돌연변이는 우리가 모델에서 만든 모든'기능', 즉 유형 돌연변이를 해결할 것이다.
  • 사용자나 게시물을 찾기 위해 API를 조회할 때마다 특정 필드나 유형이 해석됩니다.이것은 우리가 사용자 > 게시물을 조회할 때마다 서버가 먼저 > 사용자를 조회한 다음에 사용자 > 게시물을 통해 (게시물은 필드의 이름입니다.)
    우리는 데이터를 서로 다른 집합에 저장하기 때문에 이렇게 해야 한다.
  • 보시다시피 해상도는 4개의 매개 변수 (parent,args,context,info) 가 있는 함수입니다.


    아버지: 부모 분석 프로그램에서 데이터를 되돌려줍니다.예: 우리는 사고 조회 > 사용자 > 게시물에 들어갑니다.게시물은 모든 데이터를 상위 매개변수로 사용자에게 반환합니다.
    args: 우리가 조회/변이에 사용하는 매개 변수가 있습니다.만약 우리가 모드를 보았다면 발표(id:id!):우편으로 배달하다매개 변수가 하나 있습니다, id.
    상하문: 상하문은 하나의 대상이다. 이것은 우리가 서버 설정에서 전달하는 모든 내용을 포함할 것이다. 우리의 예시에서 사용자와post에 사용되는 demongo모델과'me', 즉 현재 로그인한 사용자를 포함한다.
    정보: 더 복잡합니다. 프리스마는 여기서 깊이 파고듭니다. https://www.prisma.io/blog/graphql-server-basics-demystifying-the-info-argument-in-graphql-resolvers-6f26249f613a
    우리가 패턴에 대해 한 것처럼 색인을 만듭니다.src/resolvers 내의 js:
    import postResolver from './postResolver';
    import userResolver from './userResolver';
    
    export default [userResolver, postResolver];
    

    6 모든 설정


    마지막으로, 우리의 색인에서.src/폴더의 js:
    import cors from 'cors';
    import express from 'express';
    import jwt from 'jsonwebtoken';
    import mongoose from 'mongoose';
    import { ApolloServer, AuthenticationError } from 'apollo-server-express';
    
    import schemas from './schemas';
    import resolvers from './resolvers';
    
    import userModel from './models/userModel';
    import postModel from './models/postModel';
    
    const app = express();
    app.use(cors());
    
    const getUser = async (req) => {
      const token = req.headers['token'];
    
      if (token) {
        try {
          return await jwt.verify(token, 'riddlemethis');
        } catch (e) {
          throw new AuthenticationError('Your session expired. Sign in again.');
        }
      }
    };
    
    const server = new ApolloServer({
      typeDefs: schemas,
      resolvers,
      context: async ({ req }) => {
        if (req) {
          const me = await getUser(req);
    
          return {
            me,
            models: {
              userModel,
              postModel,
            },
          };
        }
      },
    });
    
    server.applyMiddleware({ app, path: '/graphql' });
    
    app.listen(5000, () => {
      mongoose.connect('mongodb://localhost:27017/graphql');
    });
    
  • de 함수 getUser를 사용합니다. 영패를 전달하고 검증합니다. 영패가 잘못되면 "me"대상은null이고 클라이언트가 요청을 실행할 수 없습니다.
  • 우리가 Apollo Server를 만들 때, 우리는 모델을 typedef로 전달하고, 해상도를 해상도로 전달하며, 상하문은 비동기 함수로 우리가 이전에 만든 함수를 해석할 것이다.사용자든 null이든 상하문은 우리가 만든mongo모델을 포함하기 때문에 우리는 해상도에서 데이터베이스를 사용할 수 있다.
  • 우리는 express 서버 중간부품을 응용 프로그램에 추가하고 API 단점을/graphql로 설정합니다.
  • 우리는 응용 프로그램의 포트를 5000으로 설정하고db에 연결합니다.우리의 데이터베이스는graphql로 명명될 것입니다.
  • 7. 신생아 테스트.

  • "사선 편차"또는 "npm 운행 편차"를 운행합니다.
  • (으)로 이동
  • 조회와 돌변!
  • 사용자 만들기
    http://localhost:5000/graphql
    로그인 사용자

    헤더에 영패를 설치하다

    게시물 작성

    게시물 조회

    나는 네가 나처럼 이것을 좋아하길 바란다.언제든지 연락 주세요!만약 네가 더 좋은 설명을 얻고 싶다면 얼마든지 물어봐라, 나는 매우 기쁘다.

    좋은 웹페이지 즐겨찾기