Inkweon Kim
Inkweon Kim

Reputation: 131

GraphQL, Apollo : Creating an efficient schema

I recently started studying server development with GraphQL and Apollo. In the code below, the formula for fetching each data is somewhat understandable.

schema.js

const { gql } = require('apollo-server');
const _ = require('lodash');

const onepieces = [
  {
    "id": "onepiece1",
    "title": "원피스 1권",
    "price": "1,360",
    "desc": "동터오는 모험의 시대"
  },
  {
    "id": "onepiece2",
    "title": "원피스 2권",
    "price": "1,360",
    "desc": "대결 버기 해적단"
  }
];
const narutos = [
  {
    "id": "naruto1",
    "title": "나루토 1권",
    "price": "1,360",
    "desc": "나루토 모험의 시작"
  },
  {
    "id": "naruto2",
    "title": "나루토 2권",
    "price": "1,360",
    "desc": "나루토와 안개마을"
  }
];

const typeDefs = gql`  
    type Onepiece { id: ID, title: String, price: String, desc: String }
    type Naruto { id: ID, title: String, price: String, desc: String }

    type Query {
        onepiece(id: String!): Onepiece,
        naruto(id: String!): Naruto,
        getOnepieces: [Onepiece],
        getNarutos: [Naruto]
    }
`;

const resolvers = {
  Query: {
    onepiece: (parent, args) => _.find(onepieces, {id: args.id}),
    naruto: (parent, args) => _.find(narutos, {id: args.id}),
    getOnepieces: () => onepieces,
    getNarutos: () => narutos
  }
};

module.exports = { typeDefs, resolvers };

But It's inefficient code. If the category of comic book increases, I should continue to add the query. So I want to improve More convenient and readable.

For example, I would like to manage the Onepiece and Naruto categories in Comic Book.

How can I improve?

Upvotes: 0

Views: 88

Answers (1)

David Maze
David Maze

Reputation: 159733

You might start by writing a GraphQL enum of the possible categories.

enum Category { ONEPIECE NARUTO }

Since both kinds of comic books have the same structure, you can have a single GraphQL type to represent them. We'll incorporate the category we just wrote so that you can tell which one is which.

type ComicBook implements Node {
  id: ID!
  category: Category!
  title: String!
  price: String!
  desc: String!
}

There's a somewhat standard convention for retrieving arbitrary GraphQL objects by their ID; while it comes from Facebook's Relay Javascript client it's not specifically tied to that client, and I'd use it here.

interface Node {
  id: ID!
}
type Query {
  node(id: ID!): Node
}

This replaces your top-level queries to retrieve specific kinds of books by ID; you could write a query like

{
  node(id: "naruto1") {
    ... on ComicBook { category title price desc }
  }
}

Now that you have the category enum, you can also write a single top-level query to return comic books possibly filtered by category

type Query {
  comicBooks(category: Category): [ComicBook!]!
}
{
  comicBooks(category: ONEPIECE) { id title price desc }
}

There's some corresponding code changes to make this work; I'd probably start by combining the two lists of comic books into one and adding a similar category field there.

Once you've done this, if you add a third category, you need to add it to the enum and add it to the data set, but you should not need to make any other changes to either the code, the GraphQL schema, or the queries.

Upvotes: 1

Related Questions