Skip to content

Apollo Server Execution

Ahrim Yang edited this page Nov 30, 2020 · 5 revisions

์ž‘์„ฑ์ž: J113 ์–‘์•„๋ฆผ

class ApolloServer

options

Schema options

  • typeDefs
    • GraphQL ์˜ schema ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” Document or documents
    • gql ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ SDL(Schema Definition Language)๋กœ ๋‚˜ํƒ€๋ƒ„
  • resolvers
    • ๊ฐ๊ฐ์˜ schema field๋ฅผ ์ฑ„์šฐ๊ธฐ ์œ„ํ•œ function๋“ค์˜ map
  • context
    • ๋ชจ๋“  resolver์—๊ฒŒ ์ „๋‹ฌ๋˜๋Š” object ๋˜๋Š” object๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
    • apollo-server-express ์—์„œ๋Š” req, res ๊ฐ€ ์ž๋™์œผ๋กœ ์ถ”๊ฐ€๋˜์–ด์žˆ์Œ
  • introspection
    • schema ์˜ ๋‚ด์šฉ์„ client๊ฐ€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ
    • default ๋Š” true, NODE_ENV๊ฐ€ production์ด๋ฉด false
  • schemaDirectives
    • map of custom schema directives
  • schema
    • GrphQL ์˜ Schema
    • Apollo Server๊ฐ€ typeDefs ์™€ resolvers๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€๋ถ€๋ถ„์˜ ์ƒํ™ฉ์—์„œ๋Š” ๋ฐ์ดํ„ฐ ํ•„์š” ์—†์Œ
    • ์ฃผ๋กœ Apollo Federation๊ณผ ๊ฐ™์ด ์‚ฌ์šฉ๋จ
  • persistedQueries
  • subscriptions
    • subscription ๊ด€๋ จ ์˜ต์…˜
    • path, keepAlive. onConnect, onDisconnect ์„ ๋ช…์‹œํ•ด์คŒ
  • rootValue
  • validationRules
Networking options
  • cors
    • apollo-server๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ CORS ์„ค์ •
    • apollo-server-{Node.js middleware}๊ฐ™์€ ๋‹ค๋ฅธ ๋ฏธ๋“ค์›จ์–ด์™€ ํ†ตํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ• ๋•Œ๋Š” ๊ฐ๊ฐ์˜ ๋ฏธ๋“ค์›จ์–ด ํ™˜๊ฒฝ์— ๋งž๊ฒŒ ์„ค์ • ํ•ด์ค€๋‹ค. (applyMiddleware)
  • cacheControl
  • formatError
  • formatResponse
  • apollo

Lifecycle options

  • plugins
  • stopOnTerminationSignals

Debugging options

  • playground
  • debug
  • logger
  • mocks
  • mockEntireSchema

ApolloServer instance

typeDefs

const typeDefs = gql`
  # A library has a branch and books
  type Library {
    branch: String!
    books: [Book!]
  }

  # A book has a title and author
  type Book {
    title: String!
    author: Author!
  }

  # An author has a name
  type Author {
    name: String!
  }

  # Queries can fetch a list of libraries
  type Query {
    libraries: [Library]
  }
`;
Naming Conventions
  • Field names: camelCase
  • Type names: PascalCase
  • Enum names Pascalcase
  • Enum values ALL_CAPS

resolvers

// Resolver map
const resolvers = {
  Query: {
    libraries(parent, args, context, info) {
      // Return array of libraries
      return libraries;
    },
  },
  Library: {
    books(parent, args, context, info) {
      // Filter the array of books to only include
      // books that are located at the correct branch
      return books.filter((book) => book.branch === parent.branch);
    },
  },
  Book: {
    // The parent resolver (Library.books) returns an object with the
    // author's name in the "author" field. Return a JSON object containing
    // the name, because this field expects an object.
    author(parent, args, context, info) {
      return {
        name: parent.author,
      };
    },
  },

  // Because Book.author returns an object with a "name" field,
  // Apollo Server's default resolver for Author.name will work.
  // We don't need to define one.
  // Author: {
  //   name(parent, args, context, info) {
  //     return parent.name;
  //   },
  // },
};

instance

  • ApolloServer instance๋ฅผ ์ƒ์„ฑํ• ๋•Œ ์„ค์ •ํ•œ ๊ฐ’์— ๋”ฐ๋ผ์„œ ์•„๋ž˜์™€ ๊ฐ™์€ instance๊ฐ€ ์ƒ์„ฑ๋จ
ApolloServer {
  graphqlPath: '/graphql',
  requestOptions: {
    tracing: true,
    cache: InMemoryLRUCache { store: [LRUCache] },
    persistedQueries: { cache: [PrefixingKeyValueCache] }
  },
  plugins: [
    { requestDidStart: [Function: requestDidStart] },
    { requestDidStart: [Function: requestDidStart] }
  ],
  toDispose: Set(2) { [Function (anonymous)], [Function (anonymous)] },
  config: {
    typeDefs: { kind: 'Document', definitions: [Array], loc: [Object] },
    resolvers: {
      Query: [Object],
      Library: [Object],
      Book: [Object],
      Upload: Upload
    },
    tracing: true
  },
  logger: Logger {},
  apolloConfig: { graphVariant: 'current' },
  parseOptions: {},
  context: undefined,
  uploadsConfig: {},
  subscriptionServerOptions: { path: '/graphql' },
  subscriptionsPath: '/graphql',
  playgroundOptions: { version: '1.7.33', settings: undefined },
  schema: GraphQLSchema {
    __validationErrors: [],
    description: undefined,
    extensions: undefined,
    astNode: undefined,
    extensionASTNodes: [],
    _queryType: Query,
    _mutationType: undefined,
    _subscriptionType: undefined,
    _directives: [ @cacheControl, @include, @skip, @deprecated, @specifiedBy ],
    _typeMap: [Object: null prototype] {
      Library: Library,
      String: String,
      Book: Book,
      Author: Author,
      Query: Query,
      CacheControlScope: CacheControlScope,
      Upload: Upload,
      Int: Int,
      Boolean: Boolean,
      __Schema: __Schema,
      __Type: __Type,
      __TypeKind: __TypeKind,
      __Field: __Field,
      __InputValue: __InputValue,
      __EnumValue: __EnumValue,
      __Directive: __Directive,
      __DirectiveLocation: __DirectiveLocation
    },
    _subTypeMap: [Object: null prototype] {},
    _implementationsMap: [Object: null prototype] {}
  schemaDerivedData: Promise {
    {
      schema: [GraphQLSchema],
      schemaHash: '',
      extensions: [],
      documentStore: [InMemoryLRUCache]
    }
  },
  cors: undefined,
  onHealthCheck: undefined
}

Apollo Server ์˜ GraphQL request ์ฒ˜๋ฆฌ ๊ณผ์ •

Parsing the query

  • ๋ฌธ์ž์—ด์„ AST(Abstract Syntax Tree)๋กœ parsing ํ•œ๋‹ค
  • ์ด ๊ณผ์ •์—์„œ ์—๋Ÿฌ๊ฐ€ ๋‚˜๋ฉด ์‹คํ–‰์„ ์ค‘๋‹จํ•˜๊ณ  client์—๊ฒŒ ์—๋Ÿฌ๋ฅผ returnํ•œ๋‹ค.

Validation

  • type, arguments, return field ๋“ฑ์ด ์ •์˜๋œ schema ์™€ ๋งž๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

Execution

How does a GraphQL server turn a query into a response?

Clone this wiki locally