Validace JSON v CI: pipeline s jsonlint, ajv a jq
Shrnutí: Validace syntaxe dokazuje, že se soubor parsuje; validace schématem dokazuje, že pole odpovídají kontraktu. V CI rozhodují jednoznačné návratové kódy, lokalizace chyb a cesty k opravě.

Stručně: v CI nechte jq empty řešit syntaxi, ajv-cli strukturu (u týmů s více formáty check-jsonschema) a Prettier styl; řetězte je po vrstvách a skončete u prvního selhání.
Projít parserem ve vašem lokálním editoru neznamená, že soubor patří do CI; projít CI také neznamená, že pole odpovídají kontraktu.
1. Oddělte validaci syntaxe od validace schématem
Sousloví „validace JSON“ se používá příliš široce, a proto týmy často volí jeden nástroj, aby řešil dva různé problémy:
| Vrstva | Na kterou otázku odpovídá | Typické nástroje | Co selhání znamená |
|---|---|---|---|
| Syntaxe | Je tento soubor platný JSON? | jq empty, jsonlint, python -m json.tool |
Závorky, čárky, uvozovky nebo kódování jsou rozbité |
| Schéma | Odpovídají pole, typy a povinné vlastnosti kontraktu? | ajv-cli, check-jsonschema |
Soubor se parsuje, ale obchodní struktura je špatná |
| Styl | Jsou odsazení a pořadí klíčů konzistentní? | Prettier, jq -S |
Formátování je nekonzistentní a diffy jsou hlučné |
Tyto vrstvy se nemohou nahradit. Soubor, který projde syntaxí, může stále selhat na schématu: {"price": "12.5"} je platný JSON, ale pokud schéma vyžaduje, aby price bylo číslo, není přijatelný. Naopak, ať je schéma sebepodrobnější, soubor bez uzavírací závorky se proti němu nikdy nezkompiluje.
Pipeline by tedy měla spustit nejprve syntaxi, poté strukturu a nakonec styl. Skončete hned, jak vrstva selže, jinak se chyba parsování vydává za chybu pole.
2. Vrstva syntaxe: jq empty je volba s minimálními závislostmi
Pokud je jq už v CI image, validace syntaxe nestojí téměř nic:
jq empty data.json
jq empty nevytváří žádný výstup; soubor jen parsuje. Při úspěchu skončí s 0 a při selhání s nenulovým kódem plus informací o řádku a sloupci. To ho dělá lehčím než tažení celého stromu závislostí Node a dobrým prvním filtrem.
Při dávkové validaci souborů JSON v repozitáři vylučte node_modules, výstup sestavení a caches třetích stran:
find . -name '*.json' \
-not -path './node_modules/*' \
-not -path './dist/*' \
-print0 | xargs -0 -n1 jq empty
-print0 a xargs -0 zvládají mezery v názvech souborů, zatímco -n1 zajišťuje jeden soubor na volání, aby chybová zpráva identifikovala viníka. Nepředávejte stovky souborů jednomu procesu; chybové zprávy se navzájem přepíšou.
jsonlint je další běžná volba, obvykle volaná jako npx jsonlint -q data.json, kde -q vypisuje jen chyby. Hlásí čísla řádků a sloupců, ale jeho údržba je méně aktivní než u jq a různé verze tolerují BOM a komentáře odlišně. Považujte ho za čitelnější syntaktický kontrolor, nikoli za validátor schématu.
3. Vrstva schématu: základy ajv-cli validate
Ajv je nejrozšířenější validátor schématu v ekosystému JavaScriptu a ajv-cli ho vystavuje jako nástroj příkazového řádku:
ajv validate -s schema.json -d data.json
-s ukazuje na soubor schématu a -d na validovaná data. Při selhání proces skončí nenulovým kódem, takže CI okamžitě selže. Skutečné projekty obvykle přidávají dva přepínače:
npx ajv-cli validate \
-s schemas/order.json \
-d 'fixtures/orders/*.json' \
--strict=false \
--errors=text
--strict=false pomáhá se staršími schématy: striktní režim považuje neznámá klíčová slova a podezřelá prohlášení required za chyby, na kterých mnoho legacy schémat selhává. --errors=text produkuje čitelný výstup, zatímco výchozí struktura JSON je lepší pro stroje. Volte podle toho, kdo výsledek konzumuje.
Musí odpovídat i verze návrhu schématu. Hlavní verze Ajv ve výchozím nastavení podporují různé návrhy a ajv-cli umí jeden vybrat pomocí --spec=draft7, --spec=draft2019 nebo --spec=draft2020. Pokud schéma deklaruje $schema: "https://json-schema.org/draft/2020-12/schema", ale CLI ho zkompiluje jako draft-07, některá klíčová slova se tiše ignorují. Více o psaní schémat a rozdílech verzí najdete v Začínáme s JSON Schema.
Validace formátů je další častý požadavek. Klíčové slovo format je ve výchozím nastavení jen anotace; aby email, date-time a uri skutečně něco vynucovaly, načtěte ajv-formats:
npx ajv-cli validate -c ajv-formats -s schema.json -d data.json
Tento krok se snadno zapomene a výsledkem je, že pole e-mailu přijme not-an-email. Před nasazením předejte pipeline jeden úmyslně neplatný záznam; to prokáže, že pravidlo je aktivní, mnohem lépe než desetkrát číst dokumentaci.
check-jsonschema: více formátů a přívětivější chyby
Pokud tým kromě JSON zpracovává YAML, TOML nebo konfiguraci GitHub Actions, check-jsonschema je pohodlnější:
check-jsonschema --schemafile schemas/config.json config/app.json
check-jsonschema --schemafile schemas/pipeline.json .github/workflows/ci.yml
Jeho praktické výhody:
- Nativní podpora YAML, která se hodí pro soubory „tvarově JSON, ale psané v YAML“, například manifesty Kubernetes a konfiguraci CI.
- Chyby obsahují cestu k souboru, číslo řádku a cestu k poli, takže náklady na lokalizaci zůstávají nízké.
- Poskytuje háček pre-commit, takže integrace je levná.
- Umí stáhnout běžná schémata ze SchemaStore, ale přijímá i lokální soubory, čímž se vyhýbá závislosti na síti.
V týmech napříč jazyky bývá Python často už přítomen, takže instalace a upgrade check-jsonschema je lehčí než údržba nástrojového řetězce Node. Nechte jq řešit syntaxi a tento nástroj strukturu; kombinace má velmi nízké náklady na údržbu.
4. Návratové kódy jsou jediný důvěryhodný signál CI
Ať je výstup sebeprepracovanější, CI čte jen návratové kódy. Časté jsou tři pasti:
| Projev | Příčina | Oprava |
|---|---|---|
| Chyby existují, ale CI je zelená | Příkaz končí ` | |
| Žádné chyby, ale CI je červená | diff považuje „nalezené rozdíly“ za selhání |
Rozlište „rozdíl“ od „chyby spuštění“ |
| Výstup chyb je zkrácený | Paralelní vícesouborový výstup se navzájem přepisuje | Spouštějte sériově nebo vypisujte po souborech |
Pamatujte na sémantiku návratových kódů jq: normální parsování vrací 0; s -e vrací výsledek výrazu false nebo null 1; chyby použití a chybějící soubory vrací 2; chyby kompilace skriptu vrací 3. Nástroje pro schémata obecně používají 0 pro úspěch, 1 pro selhání validace a 2 pro chyby nástroje nebo argumentů. Při psaní obalu neshrnujte každý nenulový kód do „data jsou špatná“, jinak se selhání prostředí chybně diagnostikuje jako problém obsahu.
5. pre-commit: zachyťte problémy před commitem
Hodnota pre-commit není „ještě jedna kontrola“; je to poskytnutí zpětné vazby vývojáři za minutu, místo aby čekal na desetiminutový běh CI. Minimální konfigurace vypadá takto:
repos:
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.33.0
hooks:
- id: check-jsonschema
files: ^configs/.*\.json$
args:
- --schemafile
- schemas/config.json
- repo: local
hooks:
- id: jq-syntax
name: jq syntax check
entry: jq empty
language: system
files: ^configs/.*\.json$
Důležité jsou dva detaily:
filesmá odpovídat jen adresářům, které je třeba validovat. Nespouštějte háčky protinode_modulesnebo generovaným souborům.- Lokální háček předpokládá, že je
jqnainstalován na vývojářském stroji. Zdokumentujte tento požadavek, nebo přejděte k háčku v kontejneru.
Pokud projekt už používá Husky a lint-staged, zkombinujte je přímo:
{
"lint-staged": {
"configs/*.json": ["jq empty", "prettier --check"]
}
}
Pamatujte, že lint-staged předává seznam staged souborů, takže příkaz musí přijmout více cest. jq empty i prettier --check to umí. Nenechte háček skenovat celý repozitář; commity se znatelně zpomalí.
6. GitHub Actions: pipeline, kterou můžete zkopírovat
Následující workflow provádí validaci syntaxe, validaci schématem a při selhání uchová report:
name: json-validate
on:
push:
paths:
- 'schemas/**'
- 'fixtures/**'
pull_request:
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Syntax check
run: |
find fixtures -name '*.json' -print0 | xargs -0 -n1 jq empty
- name: Schema check
run: |
npx --yes ajv-cli validate \
-s schemas/order.json \
-d 'fixtures/orders/*.json' \
--strict=false \
--errors=text
Filtr paths zabraňuje tomu, aby změny jen v dokumentaci spouštěly validaci. npx --yes se hodí pro repozitáře bez zafixovaných závislostí; produkční projekty by měly přidat ajv-cli do devDependencies a verzi zafixovat. Bez lockfile může upstream release, který změní výchozí návrh nebo striktní režim, obrátit pipeline naruby přes noc.
7. Lokalizace chyb: od čísel řádků k cestám polí
Polovina hodnoty validátoru je detekce; druhá polovina je lokalizace. Naučte se číst tři druhy výstupu:
- Syntaktické chyby:
jqhlásí řádek a sloupec, často s blízkým úryvkem. Nejprve opravte závorky a čárky; nepodezírejte hned kódování. - Chyby schématu:
instancePathv Ajv ukazuje na místo v datech (například/items/0/price),schemaPathukazuje na pravidlo (například#/properties/items/items/properties/price/type) akeywordpojmenovává porušené omezení. - Chyby formátu: když kontrola
formatselže, zpráva často jen řekne „must match format "email"“. Zkombinujte ji sinstancePath, abyste identifikovali pole.
Vložte instancePath do záznamu vyšetřování; je mnohem užitečnější než zeď JSON. U polí vám číselný index navíc řekne, který záznam selhal. Pokud je obchodní klíč intuitivnější, přidejte později mapovací řádek, například items[0].id = ORD-042.
Běžné chyby schématu, jako nadužívání additionalProperties: false nebo psaní větví oneOf, které se ve skutečnosti překrývají, pokrývá Častá úskalí generování JSON Schema. Špatné validační pravidlo je nebezpečnější než žádná validace, protože vytváří falešný pocit bezpečí.
8. Tabulka výběru nástroje
| Potřeba | Doporučený nástroj | Proč | Pozor na |
|---|---|---|---|
| Jen syntaxe | jq empty |
Nulové závislosti, rychlý, jasné návratové kódy | Mezery v názvech souborů při dávkovém běhu |
| Přívětivější chyby řádků a sloupců | jsonlint |
Čitelný výstup | Aktivita údržby je omezená |
| Validace JSON Schema | ajv-cli |
Zralý ekosystém, strukturované chyby | Slaďte verze návrhů a načtěte podporu format |
| Repozitář se smíšeným JSON a YAML | check-jsonschema |
Více formátů, přívětivý k pre-commit | Zdroj schématu a přístup k síti |
| Rychlá zpětná vazba před commitem | pre-commit / lint-staged | Zpracovává jen staged soubory | Háčky musí přijmout více cest |
| Konzistentní formátování | Prettier | Široce přijímaný | Použijte --check, když nechcete soubory přepisovat |
Jedno závěrečné doporučení: ověřte, že pipeline skutečně selhává, tím, že jí nejprve předáte jeden úmyslně neplatný záznam. Největší riziko není složitá konfigurace; je to konfigurace, která nikdy neúčinkuje. Považovat „umí selhat“ za kritérium přijetí je spolehlivější než považovat „prochází“ za něj. Širšímu nástrojovému řetězci příkazového řádku se věnuje Editory, příkazový řádek a automatizace.
Časté dotazy
Mám použít jq empty, nebo jsonlint?
V CI preferujte jq empty: nulové závislosti, rychlý start a jasná sémantika návratových kódů. jsonlint použijte, když potřebujete přívětivější zprávy o řádcích a sloupcích nebo vyšetřujete lokálně. Oba provádějí pouze validaci syntaxe; ani jeden nekontroluje strukturu polí.
Proč ajv hlásí neznámé klíčové slovo?
Nejprve potvrďte, že návrh $schema ve schématu odpovídá verzi, kterou CLI používá. Mnoho chyb „neznámé klíčové slovo“ jsou klíčová slova nového návrhu, na která narazil starší kompilátor. Pokud verze odpovídají, zkontrolujte překlep. --strict=false může udržet legacy schémata v chodu, ale nespoléhejte se na něj dlouhodobě, aby skryl skutečné problémy.
Validace schématem projde, ale API stále selhává. Proč?
Schéma validuje strukturu, nikoli obchodní sémantiku. Například status může být řetězec s legálním výčtem, zatímco stavový automat zakazuje přechod přímo z paid do refunded. Taková pravidla patří do kódu nebo databázových omezení, nikoli do JSON Schema.
Jak rychle najít selhávající pole?
Přečtěte instancePath nebo číslo řádku z výstupu nástroje. instancePath v Ajv je JSON Pointer, který ukazuje přímo na data; check-jsonschema hlásí soubor a řádek. Zaznamenejte cestu a zmapujte ji na obchodní klíč; lokalizace problému obvykle zabere minuty.
Má pre-commit spouštět úplnou validaci?
Ne. pre-commit má zpracovávat jen staged soubory, aby commity zůstaly rychlé. Úplné skeny patří do CI nebo naplánovaných úloh. Rozdělení je jednoduché: lokální běhy preferují rychlost, CI úplnost.