Chapter 29Lesson 03~300 minutes

REST API, GraphQL API, Webhooks, System Hooks, Pagination, Rate Limits, and Automation: Configuration, Design Choices, and Tradeoffs

Choose deliberately between REST and GraphQL, high-level glab and glab api, project/group/system hooks, polling and events, and broad versus narrow automation identities.

ArchitectureAPI choiceHooksPollingLeast privilege

Learning objectives

  • Choose REST or GraphQL based on data shape, stability, error semantics, and client complexity.
  • Choose high-level glab commands, glab api, or a custom client deliberately.
  • Choose project, group, or system hook according to scope and administrator boundary.
  • Combine polling/reconciliation with events when completeness matters.
  • Justify token scope, idempotency, maintainability, performance, and cost tradeoffs.
Availability baseline — verified 2026-08-22 against GitLab 19.3. REST, GraphQL, glab api, and project webhooks have Free-compatible paths across GitLab.com, Self-Managed, and Dedicated. Group webhooks require Premium/Ultimate. System hooks are instance-wide administrator controls documented for Self-Managed and Dedicated, while the current System Hooks REST API reference is Self-Managed-specific. New webhooks should prefer the GitLab 19.1+ HMAC-SHA256 signing-token mechanism. The mandatory chapter path uses a GitLab Free disposable project, a local synthetic receiver, and one harmless label mutation; it does not require a public webhook endpoint, paid tier, administrator access, or production token.

1. REST versus GraphQL

REST is usually the simplest choice when a stable resource endpoint maps directly to the operation. GraphQL is useful when one consumer needs a typed projection across related GitLab objects or wants to avoid multiple round trips. Neither is automatically “more modern” or “more secure”; both enforce GitLab authorization and both require complete pagination/error handling.

Decision factor REST GraphQL
Resource model Endpoint/resource oriented Schema/field oriented
Pagination Offset or selected keyset; follow returned links Cursor connections; pageInfo
Errors HTTP status + body HTTP transport plus top-level and mutation payload errors
Data shaping Often fixed response plus query parameters Consumer selects fields/relationships
Change sensitivity Endpoint deprecations/version docs Schema field deprecations/type evolution
Best fit Simple CRUD, documented machine endpoint Cross-object read models and typed graph traversal

2. High-level glab versus glab api versus custom client

Client Use when Tradeoff
High-level glab A documented command exactly represents the human/automation task Convenient, but command output/flags can evolve; request structured output when scripting.
glab api You need documented REST/GraphQL behavior with glab authentication/host resolution Excellent for shell automation; you own status/data interpretation and idempotency.
Custom client Long-lived integration needs durable state, metrics, retry policy, queues, schemas, tests More engineering effort but best control over reliability and observability.

Never scrape GitLab HTML or pretty terminal output when a documented JSON interface exists.

3. Project, group, or system hook?

Surface Availability / owner Scope Best use
Project webhook Free all offerings; project Maintainer/Owner One project Application-specific integrations and event delivery.
Group webhook Premium/Ultimate; group Owner Group hierarchy according to configuration Central integration for a governed group.
System hook Instance administrator; feature docs cover Self-Managed/Dedicated Instance-wide administrative events Platform operations, provisioning, or enterprise integration.
System Hooks REST API Current API reference: Self-Managed admin Instance hook configuration Admin automation where that API is supported.

Do not use a system hook merely to avoid creating project-level configuration. Wider event scope increases sensitive payload exposure, blast radius, and operational ownership.

4. Polling versus event-driven: completeness and latency are different requirements

Webhooks reduce latency and waste, but they are delivery notifications rather than a transactional replica of GitLab. A resilient indexer often uses both: paginated API reconciliation establishes/repairs complete state, while webhooks trigger fast incremental work. Store a checkpoint such as last successful reconciliation time and stable resource IDs; do not trust event order as the only state model.

5. Authentication choice: match lifetime and scope to the automation

Use a job token when the exact endpoint supports it and the automation runs inside CI. Use a project/group access identity when supported and when ownership should follow that resource. Use personal/OAuth identity only when user delegation is actually intended. A broad api personal token is not the default merely because it is easy.

Authentication ≠ authorization. Possessing a valid token proves identity; roles, resource membership, endpoint support, protected resources, and tier/offering still determine what the call may do.

6. Desired-state automation beats “send command and hope”

For mutable resources, encode a natural key and desired fields. Read the object, decide create/update/no-op, write once, then read back. This design makes process restarts and uncertain timeouts safer. Where a GitLab endpoint or event surface exposes a stable idempotency/delivery key, preserve and reuse that mechanism rather than inventing a weaker local surrogate.

7. Worked scenario: organization build notification service

A platform team wants CI failures from 70 projects. On Free, requiring a group webhook would fail the tier constraint. A workable design is project webhooks managed from a project inventory plus a periodic API reconciliation. If the namespace later moves to Premium/Ultimate and central group ownership is appropriate, a group webhook can reduce per-project configuration. A system hook would be unnecessarily broad unless the integration truly needs instance-wide events and is owned by administrators.

Concern Decision
Maintainability Represent webhook configuration as inventory/desired state; reconcile drift.
Security Prefer signing tokens; rotate safely; receiver logs only selected metadata.
Reliability Queue after verification, dedupe event IDs, reconcile periodically.
Compatibility Version-test event fields and API endpoints against supported GitLab versions.
Performance Batch/read paginated state and avoid high-frequency full scans.
Cost Keep event work small; avoid unnecessary CI/polling compute and external API load.

Knowledge check

When is GraphQL a better fit than REST?

Why combine webhooks with periodic reconciliation?

Can a Free project rely on a group webhook?

When is a system hook appropriate?

What is the safest default after an uncertain write timeout?

8. Summary and next bridge

Production automation is an architecture decision, not a collection of curl examples. Lesson 4 applies these choices to failures that can silently corrupt state or weaken trust.

Primary sources and version notes

These lessons were finalized against current official GitLab documentation on 2026-08-22. API fields, rate limits, webhook event schemas, CLI flags, and tier/offering availability can change, so production clients should pin/document assumptions and re-check the API/CLI documentation for the deployed GitLab version.

Next lesson

Diagnostics, Failure Modes, Security, and Performance

Diagnose silent truncation, partial errors, duplicate writes, forged/replayed events, 429 storms, and token overreach.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.