Skip to content
Santekno.com | Tech Tutorials and Trends
EN
📖 0%
18 Jul 2025 · 6 min read ·Article 18 / 125
Go

18 Defining the `User` Data Type in a GraphQL Schema

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

18 Defining the User Data Type in a GraphQL Schema

In an era where modern applications build client-server communication ever faster, GraphQL has increasingly become the go-to choice for defining data. One of the keys to a successful GraphQL implementation on the server side is defining a data type schema that is robust, clear, and still flexible. In this article, we will thoroughly explore 18 data type definitions for the User entity that are commonly used in professional GraphQL schemas, including code examples, query simulations, and data flow visualizations to make everything easier to understand.


Why Are Data Type Definitions So Important in GraphQL?

GraphQL works on a schema-first basis, meaning the contract between the back end and front end must be agreed upon before further development begins. Strong data type definitions help to:

  • Standardize the payload structure through clearly defined types.
  • Make data validation easier on both the server and client sides.
  • Reduce bugs caused by misinterpreting fields.
  • Improve automatic API documentation.

18 User Data Type Definitions in GraphQL

Let’s simulate this together. Here are the User data types that frequently appear in modern business logic schemas:

#FieldTypeDescription
1idID!Unique user ID (cannot be null, usually a UUID)
2usernameString!Unique username
3emailString!User’s email (usually must be unique)
4fullNameStringFull name
5phoneStringPhone number, optional
6avatarUrlStringProfile photo URL, optional
7bioStringBio or short description, optional
8createdAtDateTime!Timestamp when the user was created
9updatedAtDateTime!Timestamp of the last update
10lastLoginDateTimeTimestamp of the last login, optional
11roles[UserRole!]!Array of user roles, at least ["USER"]
12isActiveBoolean!Whether the user is active or suspended
13addressAddressAssociated address, optional
14settingsUserSettingsUser preferences, optional (dark mode, etc.)
15posts[Post!]!List of posts owned by the user
16followersCountInt!Total followers
17followingCountInt!Total accounts being followed
18friends[User!]!Relationship with other users; e.g., a friendship feature
Danger
Note: Optional fields are not required to be returned by the server, so strong nullability handling is needed on the client.

Example GraphQL Schema Definition

Let me show you the complete schema definition directly in GraphQL SDL (schema definition language):

graphql
 1scalar DateTime
 2
 3enum UserRole {
 4  USER
 5  ADMIN
 6  MODERATOR
 7}
 8
 9type Address {
10  street: String
11  city: String
12  province: String
13  postalCode: String
14  country: String
15}
16
17type UserSettings {
18  theme: String
19  notifications: Boolean
20}
21
22type Post {
23  id: ID!
24  title: String!
25  content: String!
26  createdAt: DateTime!
27}
28
29type User {
30  id: ID!
31  username: String!
32  email: String!
33  fullName: String
34  phone: String
35  avatarUrl: String
36  bio: String
37  createdAt: DateTime!
38  updatedAt: DateTime!
39  lastLogin: DateTime
40  roles: [UserRole!]!
41  isActive: Boolean!
42  address: Address
43  settings: UserSettings
44  posts: [Post!]!
45  followersCount: Int!
46  followingCount: Int!
47  friends: [User!]!
48}

Query Simulation: Fetching User Data

Suppose a client wants to fetch a user’s data along with the details of their posts and friends:

graphql
 1query {
 2  user(id: "user-123") {
 3    id
 4    username
 5    fullName
 6    email
 7    createdAt
 8    roles
 9    isActive
10    posts {
11      id
12      title
13      createdAt
14    }
15    friends {
16      id
17      username
18    }
19  }
20}

The response sent by the server might look like this:

json
 1{
 2  "data": {
 3    "user": {
 4      "id": "user-123",
 5      "username": "john_doe",
 6      "fullName": "John Doe",
 7      "email": "john@example.com",
 8      "createdAt": "2024-06-10T15:30:00Z",
 9      "roles": ["USER"],
10      "isActive": true,
11      "posts": [
12        { "id": "p1", "title": "Hello GraphQL", "createdAt": "2024-05-01T09:00:00Z" }
13      ],
14      "friends": [
15        { "id": "user-234", "username": "jane_smith" }
16      ]
17    }
18  }
19}

Type Relationship Diagram: Mermaid

To make things clearer, here is a diagram of the relationships between the types in the schema above:

MERMAID
erDiagram
    User ||..o| Post : creates
    User ||..|| Address : has
    User ||..|| UserSettings : owns
    User ||..o| User : friends-with
    User }o--|{ UserRole : has

Explanation:

  • UserPost: One user can have many posts.
  • UserAddress & UserSettings: Each user can have one address and one set of settings preferences.
  • UserUser: A friendship relationship between users.
  • UserUserRole: One user can have several roles.

Best Practices for Defining the User Schema

  1. Nullable Fields: Use nullable fields (String, without the ! mark) for non-mandatory information (e.g., bio, avatarUrl).
  2. Enums and Arrays: For fields like roles, use an enum so that only certain values are permitted.
  3. Relationships to Other Types: The User type can have relationships to other types (posts, address, settings) to normalize data.
  4. Count Fields: Always separate array relationship fields (posts, friends) from their counts (followersCount) for efficiency on the front end.
  5. Timestamps: Use the DateTime scalar with the ISO 8601 standard.
  6. Recursive Fields: The friends: [User!]! relationship supports mutual friendship features.
  7. Security: Never expose passwords or tokens in the schema!

Case Study: New User Registration Flow

Let’s simulate the registration flow for a new user with the minimum required fields:

MERMAID
sequenceDiagram
    participant C as Client
    participant S as GraphQL Server
    C->>S: mutation { registerUser(username, email, password) }
    S-->>C: { id, username, email, createdAt, roles }

In the flow above, the server only returns the fields the client needs after registration. Other fields such as friends, address, and settings can be filled in later after login.


Conclusion

Defining data types in a GraphQL schema is the primary foundation for building an API that is structured, consistent, and scalable. The User type is especially important because almost every modern digital product—from SaaS and marketplaces to social networks—is built on a user entity rich in information and relationships.

Starting from the 18 field definitions above, you can extend the User type to fit your specific business needs. However, make sure you always maintain a clean schema, strong typing, and think about nullability from the very start. Implementing best practices in your GraphQL schema not only speeds up development but also improves the experience for front-end developers and QA engineers down the road.

It’s time to work with a proper schema! 🚀


Sources & References:

Related Articles

💬 Comments