Defining the TypeDefs for your Apollo Server Project
Learn how to define your GraphQL schema using the `gql` tag and structure your `typeDefs` for use in an Apollo Server project.

Previously in this course, we covered installing Apollo Server: your GraphQL API foundation to prepare our Node.js environment. Now that our dependencies are installed, we need to bridge the gap between our conceptual data models—like those we discussed in defining custom object types: mastering data modeling in GraphQL—and our actual running server.
In this lesson, we will translate your Schema Definition Language (SDL) into a JavaScript object using the gql template literal. This typeDefs constant will serve as the single source of truth for your API's structure.
What are typeDefs?
In Apollo Server, typeDefs (short for Type Definitions) is the variable that holds your entire GraphQL schema. It is a string—but not just any string. It must be wrapped in a special tagged template literal called gql.
The gql tag performs two critical functions:
- Parsing: It parses your SDL string into an Abstract Syntax Tree (AST) that Apollo Server can understand.
- Validation: It provides syntax highlighting and validation in your IDE, ensuring you don't have typos in your schema structure.
Without this, your schema would just be a static string, and the server wouldn't know how to validate incoming queries against your types.
Defining your schema in code

To define your typeDefs, you'll typically create a file named schema.js or typeDefs.js in your project root. Here is how you structure that file.
JAVASCRIPT// schema.js const { gql } = require(CE9178">'apollo-server'); const typeDefs = gqlCE9178">` type Task { id: ID! title: String! completed: Boolean! } type Query { tasks: [Task] } `; module.exports = typeDefs;
Breaking down the export
- The Import: We import
gqlfrom theapollo-serverpackage. If you are using newer versions of Apollo Server (v4+), this may be imported from@apollo/server. - The Tagged Template: We use the backtick (
`) syntax followed by thegqltag. This allows us to write multi-line strings that the server can parse as valid GraphQL. - The Export: By using
module.exports, we make this schema available to our main server entry point (usuallyindex.jsorserver.js).
Advancing the project: Initializing the schema
In our ongoing task manager API project, we are ready to define our first core entity. Open your project and create a file named schema.js.
Practice Exercise:
- Create a
schema.jsfile. - Define a
Tasktype with the following fields:id(ID),title(String), andisDone(Boolean). - Add a
Querytype with a field calledgetTasksthat returns a list ofTaskobjects. - Export your
typeDefs.
Hint: Remember that non-nullable fields use the ! syntax, which we explored in enforcing data with non-null fields in GraphQL.
Common Pitfalls
- Forgetting the
gqltag: If you pass a standard string to Apollo Server instead of agql-tagged template, the server will throw an error because it cannot parse the raw string. - Case sensitivity: GraphQL types are case-sensitive. If you define a type
Taskbut try to return atasktype in your resolver, the server will fail to match them. - Missing Query type: A GraphQL schema must have a
Querytype defined if you want to perform any read operations. Even if your API is simple, always include at least an emptyQuerytype.
FAQ
Q: Can I split my typeDefs into multiple files?
Yes, but you'll need to combine them before passing them to the Apollo Server constructor. You can store them in an array and use gql to parse them collectively.
Q: Does the order of types matter in the typeDefs?
Generally, no. As long as all referenced types are defined somewhere in the typeDefs string, the order does not matter.
Q: Should I put my typeDefs in the same file as my server code?
For very small projects, yes. However, as your API grows, it is best practice to keep your schema in a dedicated schema.js file to maintain a clean codebase.
Recap
We have successfully moved from conceptual modeling to concrete code. By wrapping our SDL in the gql tag, we created a typeDefs constant that serves as the contract for our API. This structure is now ready to be imported into our server and paired with the logic that will actually fetch our data.
Up next, we will move to Creating Basic Resolvers, where we will write the functions that actually fulfill the requests defined in this schema.



