GraphQL tiến hoá bằng cách thêm field mới và đánh dấu field cũ là không dùng nữa.
Client cũ vẫn chạy vì field cũ còn đó, và field cũ chỉ bị gỡ khi không còn ai truy vấn tới.
graphql
type User {
firstName: String!
fullName: String! @deprecated(reason: "Use firstName/lastName. Removed 2026-12-01")
}Điều kiện để cách này hoạt động là phải biết ai đang dùng field nào. Không có số liệu sử dụng theo field thì không ai dám gỡ, và schema phình lên theo thời gian.
Các breaking change cần chặn trong CI: gỡ field hoặc kiểu; đổi kiểu trả về; thêm tham số bắt buộc; và đổi một field cho phép null thành không null theo chiều sai.
Với ứng dụng di động, thời gian sống của một phiên bản client tính bằng năm vì luôn có người không cập nhật. Lịch gỡ field nên tính theo số liệu sử dụng thật chứ không theo mốc thời gian định sẵn.