Cand aveti de-a face cu date complexe si structurate, trebuie sa determinati daca datele sunt valabile sau nu. JSON-Schema este standardul documentelor JSON care descrie structura si cerintele datelor dvs. JSON. In aceasta serie din doua parti, veti invata cum sa utilizati JSON-Schema pentru validarea datelor.

Sa presupunem ca aveti o baza de date de utilizatori in care fiecare inregistrare arata similar cu acest exemplu:

{“id”: 64209690, “nume”: “Jane Smith”, “email”: “[email protected]”, “telefon”: “07777 888 999”, “adresa”: {“strada”: ” Flat 1, 188 High Street Kensington “,” cod postal “:” W8 5AA “,” oras “:” Londra “,” tara “:” Regatul Unit “},” personal “: {” DOB “:” 1982-08- 16 “,” varsta “: 33,” gen “:” femeie “},” conexiuni “: [{” id “:” 35434004285760 “,” nume “:” John Doe “,” connType “:” prieten “,” since “:” 2014-03-25 “}, {” id “: 13418315,” name “:” James Smith “,” connType “:” relativ “,” relation “:”sot”, “since”: “2012-07-03”}], “feeds”: {“news”: true, “sport”: true, “fashion”: false}, “createdAt”: “2015-09 -22T10: 30: 06.000Z “}

Intrebarea cu care vom trata este cum sa stabilim daca inregistrarea ca cea de mai sus este valabila sau nu.

Exemplele sunt foarte utile, dar nu sunt suficiente pentru a descrie cerintele dvs. de date. JSON-Schema vine la salvare. Aceasta este una dintre schemele posibile care descriu o inregistrare a utilizatorului:

{“$ schema”: “https://json-schema.org/draft-04/schema#”, “id”: “http://mynet.com/schemas/user.json#”, “title”: “User”, “description”: “Profil utilizator cu conexiuni”, “type”: “obiect”, “proprietati”: {“id”: {“description”: “numar intreg pozitiv sau sir de cifre”, “tip”: [“string”, “numar intreg”], “pattern”: “^ [1-9] [0-9] * $”, “minimum”: 1}, “name”: {“type”: “sir”, “maxLength”: 128}, “email”: {“type”: “string”, “format”: “email”}, “phone”: {“type”: “string”, “pattern”: “^ [0 -9 () \ – \. \ S] + $ “},” adresa “:{“type”: “obiect”, “adicionalProperties”: {“type”: “string”}, “maxProperties”: 6, “obligatoriu”: [“strada”, “cod postal”, “oras”, “tara”] }, “personal”: {“type”: “obiect”, “Properties”: {“DOB”: {“type”: “string”, “format”: “data”}, “age”: {“type” : “numar intreg”, “minim”: 13}, “sex”: {“enum”: [“femeie”, “barbat”]}} “necesar”: [“DOB”, “varsta”], “AditionalProprietati”: false}, “conexiuni”: {“type”: “array”, “maxItems”: 150, “items”: {“title”: “Conexiune “,” descriere “:” Schema conexiune utilizator “,” tip “:” obiect “,” proprietati “: {” id “: {” type “: [” string “,” numar intreg “],” pattern “:” ^ [1-9] [0-9] * $ “,” minim “: 1},” nume “: {” type “:” sir “,” maxLength “: 128},” since “: {” type ” : “string”, “format”: “data”}, “connType”: {“type”: “string”}, “relation”: {}, “close”: {}}, “oneOf”: [{” Properties “: {” connType “: {” enum “: [” relativ “]},” relation “: {” type “:” string “}},” dependencies “: {” relation “: [” close “]} },{“properties”: {“connType”: {“enum”: [“prieten”, “coleg”, “alt”]}, “relation”: {“not”: {}}, “close”: {“not “: {}}}}],” obligatoriu “: [” id “,” nume “,” de cand “,” connType “],” adicionalProperties “: false}},” feeds “: {” title “:” feeduri “,” description “:” Feed-urile utilizatorului se aboneaza la “,” type “:” obiect “,” patternProperties “: {” ^ [A-Za-z] + $ “: {” type “:” boolean “}}, “additionProperties”: false}, “createdAt”: {“type”: “string”, “format”: “data-ora”}}}[“prieten”, “coleg”, “altul”]}, “relatie”: {“nu”: {}}, “apropiat”: {“nu”: {}}}}], “necesar”: [” id “,” name “,” since “,” connType “],” adicionalProperties “: false}},” feeds “: {” title “:” feeds “,” description “:” Feed-uri utilizatori abonati la “,” tip “:” obiect “,” patternProperties “: {” ^ [A-Za-z] + $ “: {” type “:” boolean “}},” adicionalProperties “: false},” createdAt “: {” type ” : “string”, “format”: “data-ora”}}}[“prieten”, “coleg”, “altul”]}, “relatie”: {“nu”: {}}, “apropiat”: {“nu”: {}}}}], “necesar”: [” id “,” name “,” since “,” connType “],” adicionalProperties “: false}},” feeds “: {” title “:” feeds “,” description “:” Feed-uri utilizatori abonati la “,” tip “:” obiect “,” patternProperties “: {” ^ [A-Za-z] + $ “: {” type “:” boolean “}},” adicionalProperties “: false},” createdAt “: {” type ” : “string”, “format”: “data-ora”}}}{“not”: {}}}}], “obligatoriu”: [“id”, “nume”, “de cand”, “connType”], “adicionalProperties”: false}}, “feeds”: {“title” : “feed-uri”, “descriere”: “Feed-uri de utilizator se aboneaza la”, “type”: “obiect”, “patternProperties”: {“^ [A-Za-z] + $”: {“type”: “boolean” }}, “additionProperties”: false}, “createdAt”: {“type”: “sir”, “format”: “data-ora”}}}{“not”: {}}}}], “obligatoriu”: [“id”, “nume”, “de cand”, “connType”], “adicionalProperties”: false}}, “feeds”: {“title” : “feed-uri”, “descriere”: “Feed-uri utilizatori abonati la”, “type”: “obiect”, “patternProperties”: {“^ [A-Za-z] + $”: {“type”: “boolean” }}, “additionProperties”: false}, “createdAt”: {“type”: “sir”, “format”: “data-ora”}}}Utilizatorii se aboneaza la “,” type “:” obiect “,” patternProperties “: {” ^ [A-Za-z] + $ “: {” type “:” boolean “}},” adicionalProperties “: false}, “createdAt”: {“type”: “string”, “format”: “data-ora”}}}Utilizatorii se aboneaza la “,” type “:” obiect “,” patternProperties “: {” ^ [A-Za-z] + $ “: {” type “:” boolean “}},” adicionalProperties “: false}, “createdAt”: {“type”: “string”, “format”: “data-ora”}}}

Aruncati o privire la schema de mai sus si inregistrarea utilizatorului pe care o descrie (care este valabila in conformitate cu aceasta schema). Sunt multe explicatii de facut aici.

Codul JavaScript pentru validarea inregistrarii utilizatorului cu schema ar putea fi:

var Ajv = necesita (‘ajv’); var ajv = Ajv ({allErrors: true}); var valid = ajv.validate (userSchema, userData); if (valid) {console.log („Datele utilizatorului sunt valide”); } else {console.log (‘Datele utilizatorului sunt INVALID!’); console.log (ajv.errors); }

sau pentru o mai buna performanta:

var validate = ajv.compile (userSchema); var valid = validate (userData); if (! valid) console.log (validate.errors);

Toate probele de cod sunt disponibile in schema GitHub repo tutsplus-json-schema. Puteti incerca, de asemenea, in browser.

Ajv, validatorul folosit in exemplu, este cel mai rapid validator JSON-Schema pentru JavaScript. L-am creat, asa ca il voi folosi in acest tutorial.

Inainte de a continua, sa ne ocupam rapid de tot ce este.

De ce validati datele ca pas separat?

  • a esua repede
  • pentru a evita coruptia datelor
  • pentru a simplifica codul de procesare
  • sa utilizeze codul de validare in teste

De ce JSON (si nu XML)?

  • la fel de larga adoptare ca XML
  • mai usor de procesat si mai concis decat XML
  • domina dezvoltarea web din cauza JavaScript

De ce sa folositi schemele?

  • declarativ
  • mai usor de intretinut
  • poate fi inteles de catre non-codificatori
  • nu este necesar sa scrieti cod, pot fi utilizate biblioteci terte open-source

De ce JSON-Schema?

  • cea mai larga adoptie dintre toate standardele de validare JSON
  • foarte matur (versiunea actuala este 4, exista propuneri pentru versiunea 5)
  • acopera o mare parte a scenariilor de validare
  • utilizeaza documente JSON usor de analizat pentru scheme
  • platforma independenta
  • usor extensibil
  • 30+ validatori pentru diferite limbi, inclusiv 10+ pentru JavaScript, deci nu este necesar sa-l codificati singur

Sarcini

Acest tutorial include cateva sarcini relativ simple care va ajuta sa intelegeti mai bine schema JSON si modul in care poate fi utilizat. Exista scripturi simple JavaScript pentru a verifica daca le-ai facut corect. Pentru a le rula, va trebui sa instalati node.js (nu aveti nevoie de experienta cu acesta). Instalati doar nvm (node ​​manager manager) si o versiune recenta node.js:

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.29.0/install.sh | bash nvm instala 4

De asemenea, trebuie sa clonati repo-ul si sa rulati npm install (va instala validatorul Ajv).

Hai sa scufundam in scheme!

JSON-schema este intotdeauna un obiect. Proprietatile sale se numesc „cuvinte cheie”. Unii dintre ei descriu regulile pentru date (de exemplu, „tip” si „proprietati”), iar unii descriu schema in sine („$ schema”, „id”, „titlu”, „descriere”) – vom ajunge la mai tarziu.

Datele sunt valide in functie de schema daca sunt valabile in functie de toate cuvintele cheie din aceasta schema – asta este foarte simplu.

Proprietati de date

Deoarece majoritatea datelor JSON constau din obiecte cu mai multe proprietati, cuvantul cheie „proprietati” este probabil cel mai frecvent utilizat cuvant cheie. Se aplica numai obiectelor (vezi sectiunea urmatoare despre ce inseamna „aplica”).

Este posibil sa fi observat in exemplul de mai sus ca fiecare proprietate din cuvantul cheie „proprietati” descrie proprietatea corespunzatoare din datele dvs.

Valoarea fiecarei proprietati este ea insasi o schema JSON – schema JSON este un standard recursiv. Fiecare proprietate din date ar trebui sa fie valabila in conformitate cu schema corespunzatoare din cuvantul cheie „proprietati”.

Lucrul important este ca cuvantul cheie „proprietati” nu face nicio proprietate necesara; defineste doar scheme pentru proprietatile care sunt prezente in date.

De exemplu, daca schema noastra este:

{“properties”: {“foo”: {“type”: “string”}}}

atunci obiectele cu sau fara proprietatea „foo” pot fi valide conform acestei scheme:

{foo: “bar”}, {foo: “bar”, baz: 1}, {baz: 1}, {} // toate valabile

si numai obiectele care au o proprietate foo care nu este un sir sunt nevalide:

{foo: 1} // nevalid

Incercati acest exemplu in browser.

Tip de date

V-ati dat deja seama ce face cuvantul cheie „tip”. Este probabil cel mai important cuvant cheie. Valoarea sa (un sir sau un sir de siruri) defineste ce tip (sau tipuri) de date trebuie sa fie valabile.

Dupa cum puteti vedea in exemplul de mai sus, datele utilizatorului trebuie sa fie un obiect.

Majoritatea cuvintelor cheie se aplica anumitor tipuri de date – de exemplu, cuvantul cheie „proprietati” se aplica numai obiectelor, iar cuvantul cheie „model” se aplica numai sirurilor.

Ce inseamna „aplica”? Sa spunem ca avem o schema cu adevarat simpla:

{“pattern”: “^ [0-9] + $”}

S-ar putea sa va asteptati ca acestea sa fie valide in conformitate cu o astfel de schema, datele trebuie sa fie un sir care sa corespunda modelului:

“12345”

Dar standardul JSON-schema specifica faptul ca daca un cuvant cheie nu se aplica tipului de date, atunci datele sunt valide in functie de acest cuvant cheie. Asta inseamna ca orice date care nu sunt de tip „sir” sunt valabile in conformitate cu schema de mai sus – numere, tablouri, obiecte, booleane si chiar nule. Daca doriti sa fie valabile doar sirurile care corespund modelului, schema dvs. trebuie sa fie:

{“type”: “sir”, “pattern”: “^ [0-9] + $”}

Din aceasta cauza, puteti face scheme foarte flexibile care vor valida mai multe tipuri de date.

Uita-te la proprietatea „id” din exemplul de utilizator. Ar trebui sa fie valabil in conformitate cu aceasta schema:

{“type”: [“string”, “numar intreg”], “pattern”: “^ [1-9] [0-9] * $”, “minimum”: 1}

Aceasta schema necesita ca datele sa fie valide sa fie fie un „sir”, fie un „numar intreg” . Exista, de asemenea, cuvantul cheie „pattern” care se aplica numai sirurilor; necesita ca sirul sa contina doar cifre si sa nu porneasca de la 0. Exista cuvantul cheie „minim” care se aplica numai la numere; necesita ca numarul sa nu fie mai mic de 1.

Un alt mod, mai veros, de a exprima aceeasi cerinta este:

{“anyOf”: [{“type”: “sir”, “pattern”: “^ [1-9] [0-9] * $”}, {“type”: “numar intreg”, “minim”: 1 },]}

Dar, din cauza modului in care este definita schema JSON, aceasta schema este echivalenta cu prima, care este mai scurta si mai rapida de validat in majoritatea validatorilor.

Tipurile de date pe care le puteti folosi in scheme sunt „obiect” , „tablou” , „numar” , „numar intreg” , „sir” , „boolean” si „nul” . Retineti ca „numar” include „numar intreg” – toate numerele intregi sunt si ele.

Validarea numerelor

Exista mai multe cuvinte cheie pentru validarea numerelor. Toate cuvintele cheie din aceasta sectiune se aplica numai numerelor (inclusiv numerelor intregi).

„Minim” si „maxim” sunt explicative. Pe langa acestea, exista cuvintele cheie „exclusiveMinimum” si „exclusiveMaximum”. In exemplul nostru de utilizator, varsta utilizatorului trebuie sa fie un numar intreg care este de 13 sau mai mare. Daca schema pentru varsta utilizatorului a fost:

{“type”: “numar intreg”, “minim”: 13, “exclusiveMinimum”: true}

atunci aceasta schema ar fi cerut ca varsta utilizatorului sa fie strict mai mare decat 13, adica cea mai mica varsta permisa sa fie 14.

Un alt cuvant cheie pentru validarea numerelor este „multipleOf”. Numele sau explica, de asemenea, ce face si puteti consulta referinta de cuvinte cheie a schemei JSON pentru a vedea cum functioneaza.

Validarea corzilor

Exista, de asemenea, mai multe cuvinte cheie pentru validarea sirurilor. Toate cuvintele cheie din aceasta sectiune se aplica numai sirurilor.

„MaxLength” si „minLength” necesita ca sirul sa nu fie mai lung sau sa nu fie mai scurt decat numarul dat. Standardul JSON-schema necesita ca o pereche unicode, de exemplu, caracter emoji, sa fie contorizata ca un singur caracter. JavaScript il considera ca doua caractere atunci cand accesati proprietatea .length a sirurilor.

Unii validatori determina lungimile sirului in functie de standard, iar altii o fac JavaScript, care este mai rapida. Ajv va permite sa specificati cum sa determinati lungimile sirului, iar implicit este respectarea standardului.

var schema = {“maxLength”: 2}; var ajv = Ajv (); // numarati perechi unicode ca un caracter ajv.validate (schema, “????????”); // adevarat ajv.validate (schema, “????????!”); // false var ajv = Ajv ({unicode: false}); // numara perechile unicode ca doua caractere ajv.validate (schema, “????”); // true ajv.validate (schema, “????!”); // fals

Ati vazut deja in actiune cuvantul cheie „pattern” – necesita pur si simplu ca sirul de date sa corespunda expresiei obisnuite definite in conformitate cu acelasi standard folosit in JavaScript. Consultati exemplul de mai jos pentru scheme si potrivirea expresiilor obisnuite:

{“pattern”: “^ [1-9] [0-9] * $”}; / ^ [1-9] [0-9] * $ /; // id {“pattern”: “^ [A-Za-z] + $”}; / ^ [Az] + $ / i; // litere {“pattern”: “^ [0-9 () \ – \. \ s] + $”}; /^[0-9()\-\.\s]+$/; // telefon

Cuvantul cheie „format” defineste validarea semantica a sirurilor, cum ar fi „e-mail” , „data” sau „data” in exemplul utilizatorului. JSON-Schema defineste, de asemenea, formatele „uri” , „hostname” , „ipv4” si „ipv6” . Validatoarele definesc formatele in mod diferit, optimizand viteza de validare sau corectitudinea. Ajv va ofera o alegere:

var ajv = Ajv (); // validarea formatului „rapid” ajv.validate ({“format”: “data”}, “2015-12-24”); // true ajv.validate ({“format”: “data”}, “2015-14-33”); // true var ajv = Ajv ({format: ‘full’); // validare mai detaliata a formatului ajv.validate ({“format”: “data”}, “2015-12-24”); // true ajv.validate ({“format”: “data”}, “2015-14-33”); // fals

Majoritatea validatorilor va permit sa definiti formate personalizate fie ca expresii obisnuite, fie ca functii de validare. Am putea defini un „telefon” format personalizat pentru schema noastra pentru a-l utiliza in mai multe locuri:

ajv.addFormat (‘telefon’, /^[0-9()\-\.\s Alan+$/);

si atunci schema pentru proprietatea telefonului ar fi:

{“type”: “sir”, “format”: “telefon”}

Sarcina 1

Creati o schema care va necesita ca datele sa fie o data (sir) sau un an (numar) si ca un an este mai mare sau egal cu 1976.

Puneti raspunsul in fisierul part1 / task1 / date_schema.json si executati nodul part1 / task1 / validat pentru a-l verifica.

Validarea obiectului

In plus fata de „proprietati”, puteti vedea alte exemple de cuvinte cheie din exemplul nostru de utilizator care se aplica obiectelor.

Cuvantul cheie „necesar” listeaza proprietatile care trebuie sa fie prezente in obiect pentru ca acesta sa fie valabil. Dupa cum va amintiti, cuvantul cheie „proprietati” nu necesita proprietati, ci le valideaza doar daca sunt prezente. „Obligatoriu” completeaza „proprietati”, permitandu-va sa definiti ce proprietati sunt necesare si care sunt optionale.

Daca am avea aceasta schema:

{“properties”: {“foo”: {“type”: “string”}}, “obligatoriu”: [“foo”]}

atunci toate obiectele fara proprietatea foo ar fi invalide.

Va rugam sa retineti ca aceasta schema inca nu necesita ca datele noastre sa fie un obiect – toate celelalte tipuri de date sunt valabile in conformitate cu aceasta. Pentru a solicita ca datele noastre sa fie un obiect, trebuie sa-i adaugam cuvantul cheie „tip”.

Incercati exemplul de mai sus in browser.

Cuvantul cheie „patternProperties” va permite sa definiti scheme conform carora valoarea proprietatii datelor ar trebui sa fie valabila daca numele proprietatii se potriveste cu expresia obisnuita. Poate fi combinat cu cuvantul cheie „proprietati” din aceeasi schema.

Proprietatea feed-urilor din exemplul de utilizator ar trebui sa fie valabila in conformitate cu aceasta schema:

{“type”: “obiect”, “patternProperties”: {“^ [A-Za-z] + $”: {“type”: “boolean”}}, “additionProperties”: false}

Pentru a fi valabile, feed-urile ar trebui sa fie un obiect cu proprietati ale caror nume constau doar din litere latine si ale caror valori sunt booleane.

Cuvantul cheie „adicionalProperties” va permite sa definiti schema conform careia toate celelalte cuvinte cheie (care nu sunt utilizate in „proprietati” si care nu se potrivesc cu „patternProperties”) ar trebui sa fie valide, sau sa interziceti alte proprietati complet, asa cum am facut in proprietatea feedurilor schema de mai sus.

In exemplul urmator, „adicionalProperties” este utilizat pentru a crea o schema simpla pentru hash de numere intregi intr-un anumit interval:

var schema = {“type”: “obiect”, “adicionalProperties” {“type”: “numar intreg”, “minim”: 0, “maxim”: 65535}}; var validate = ajv.compile (schema); validati ({a: 1, b: 10, c: 100}); // true validate ({d: 1, e: 10, f: 100000}); // false validate ({g: 1, h: 10, i: 10.5}); // false validate ({j: 1, k: 10, l: ‘abc’}); // fals

Cuvintele cheie „maxProperties” si „minProperties” va permit sa limitati numarul de proprietati din obiect. In exemplul nostru de utilizator, schema pentru proprietatea adresei este:

{“type”: “obiect”, “adicionalProperties”: {“type”: “string”}, “maxProperties”: 6, “obligatoriu”: [“strada”, “cod postal”, “oras”, “tara”] }

Aceasta schema necesita ca adresa sa fie un obiect cu proprietatile necesare strada, cod postal, oras si tara, sa permita doua proprietati suplimentare („maxProperties” este 6) si necesita ca toate proprietatile sa fie siruri.

„Dependente” este probabil cel mai complex si confuz si cel mai rar utilizat cuvant cheie, dar este un cuvant cheie foarte puternic in acelasi timp. Va permite sa definiti cerintele pe care datele ar trebui sa le satisfaca daca au anumite proprietati.

Exista doua tipuri de astfel de cerinte pentru obiect: a avea alte proprietati (se numeste „dependenta de proprietate”) sau satisfacerea unei scheme („dependenta de schema”).

In exemplul nostru de utilizator, una dintre schemele posibile cu care conexiunea de utilizator ar trebui sa fie valabila este urmatoarea:

{“properties”: {“connType”: {“enum”: [“relativ”]}, “relation”: {“type”: “string”}}, “dependencies”: {“relation”: [“close” ]}}}

Este necesar ca proprietatea connType sa fie egala cu „relativa” (consultati cuvantul cheie „enum” de mai jos) si ca, daca proprietatea relatiei este prezenta, aceasta este o sir.

Nu este necesar ca aceasta relatie sa fie prezenta, dar cuvantul cheie „dependente” necesita ca, daca proprietatea relatiei este prezenta, DESI proprietatea apropiata ar trebui sa fie prezenta.

Nu exista reguli de validare definite pentru proprietatea apropiata in schema noastra, desi din exemplu putem vedea ca probabil trebuie sa fie boolean. Unul dintre modurile in care am putea corecta aceasta omisiune este schimbarea cuvantului cheie „dependente” pentru a utiliza „schema dependenta”:

“dependencies”: {“relation”: {“properties”: {“close”: {“type”: “boolean”},}, “obligatoriu”: [“inchide”]}}

Va puteti juca cu exemplul de utilizator actualizat in browser.

Retineti ca schema din proprietatea „relatie” din cuvantul cheie „dependente” este utilizata pentru a valida obiectul parinte (adica conexiune) si nu valoarea proprietatii relatiei din date.

Sarcina 2

Baza de date contine oameni si masini. Folosind doar cuvintele cheie pe care le-am explicat pana acum, creati o schema pentru a le valida ambele. Un obiect uman esantion:

{“uman”: adevarat, “nume”: “Jane”, “gen”: “femeie”, “DOB”: “1985-08-12”}

Un obiect de masina exemplu:

{“model”: “TX1000”, “made”: “2013-08-29”}

Retineti ca ar trebui sa fie o schema care sa valideze atat oamenii, cat si masinile, nu doua scheme.

Puneti raspunsul in fisierul part1 / task2 / human_machine_schema.json si executati nodul part1 / task2 / validat pentru a-l verifica.

Sugestii: utilizati cuvantul cheie „dependente” si cautati in fisierul part1 / task2 / invalid.json pentru a vedea ce obiecte ar trebui sa fie invalide.

Ce obiecte care probabil ar trebui sa fie invalide nu se afla in fisierul invalid.json?

Principala preluare a acestei sarcini este faptul ca scopul validarii nu este doar validarea tuturor obiectelor valabile ca fiind valide. Am auzit acest argument de nenumarate ori: „Aceasta schema imi valideaza datele valide ca fiind valide, de aceea este corecta.” Acest argument este gresit, deoarece nu trebuie sa faceti mare lucru pentru a-l realiza – o schema goala va face treaba, deoarece valideaza toate datele ca fiind valide.

Cred ca scopul principal al validarii este validarea datelor nevalide ca nevalide si de aici provine toata complexitatea.

Validare Array

Exista mai multe cuvinte cheie pentru a valida matricile (si se aplica numai pentru tablele)

„MaxItems” si „minItems” necesita ca tabloul sa nu aiba mai mult (sau nu mai putin) decat un anumit numar de elemente. In exemplul utilizatorului, schema necesita ca numarul de conexiuni sa nu depaseasca 150.

Cuvantul cheie „elemente” defineste o schema (sau scheme) conform careia elementele ar trebui sa fie valide. Daca valoarea acestui cuvant cheie este un obiect (ca in exemplul utilizatorului), atunci acest obiect este o schema conform careia datele ar trebui sa fie valide.

Daca valoarea cuvantului cheie „elemente” este un tablou, atunci acest tablou contine scheme conform carora elementele corespunzatoare ar trebui sa fie valide:

{“type”: “array”, “items”: [{“type”: “numar intreg”}, {“type”: “string”}]}

Schema din exemplul simplu de mai sus necesita ca datele sa fie un tablou, cu primul element care este un numar intreg si al doilea care este un sir.

Ce zici de articole dupa aceste doua? Schema de mai sus nu defineste cerintele pentru alte articole. Acestea pot fi definite cu cuvantul cheie „titluri suplimentare”.

Cuvantul cheie „titluri suplimentare” se aplica numai situatiei in care cuvantul cheie „elemente” este un tablou si exista mai multe elemente in date decat in ​​cuvantul cheie „elemente”. In toate celelalte cazuri (nu exista niciun cuvant cheie „elemente”, este un obiect sau nu exista mai multe elemente in date), cuvantul cheie „Articole suplimentare” va fi ignorat, indiferent de valoarea acestuia.

Daca cuvantul cheie „aditional” este adevarat, acesta este pur si simplu ignorat. Daca este falsa si datele au mai multe elemente decat cuvantul cheie „elemente” – atunci validarea esueaza:

var schema = {“type”: “array”, “items”: [{“type”: “numar intreg”}, {“type”: “sir”}], “ExtraItems”: false}; var validate = ajv.compile (schema); console.log (validare ([1, “foo”, 3])); // fals

Daca cuvantul cheie „suplimentItems” este un obiect, atunci acest obiect este o schema conform careia toate elementele suplimentare ar trebui sa fie valide:

var schema = {“type”: “array”, “items”: [{“type”: “integer”}, {“type”: “string”}], “adicionalItems”: {“type”: “integer” }}; var validate = ajv.compile (schema); console.log (validare ([1, “foo”, 3])); // true console.log (validare ([1, “foo”, 3, 4])); // true console.log (validare ([1, “foo”, “bar”])); // fals

Va rugam sa experimentati cu aceste exemple pentru a vedea cum functioneaza „articolele” si „obiectele suplimentare”.

Ultimul cuvant cheie care se aplica matricilor este „UniqueItems”. Daca valoarea sa este adevarata, necesita pur si simplu ca toate elementele din tabla sa fie diferite.

Validarea cuvantului cheie „uniqueItems” poate fi costisitoare din punct de vedere al calculului, astfel incat unii validatori au ales sa nu-l implementeze sau sa faca acest lucru doar partial.

Ajv are o optiune de a ignora acest cuvant cheie:

var schema = {“type”: “array”, “UniqueItems”: true}; var ajv = Ajv (); // validare uniqueItems ajv.validate (schema, [1, 2, 3]); // adevarat ajv.validate (schema, [1, 2, 2]); // false var ajv = Ajv ({uniqueItems: false}); // ignora uniqueItems ajv.validate (schema, [1, 2, 3]); // adevarat ajv.validate (schema, [1, 2, 2]); // Adevarat

Sarcina 3

Unul dintre modurile de a crea un obiect date in JavaScript este sa treci de la 2 la 7 numere la constructorul Date:

var data = data noua (2015, 2, 15); // Sun 15 15 2015 00:00:00 GMT + 0000, luna este 0 bazata var data2 = Data noua (an, luna0, zi, ora, minut, secunde, ms);

Ai un tablou. Creati o schema care va valida faptul ca aceasta este o lista valida de argumente pentru constructorul Date.

Puneti raspunsul in fisierul part1 / task3 / date_args_schema.json si executati nodul part1 / task3 / validat pentru a-l verifica.

Cuvinte cheie „Enum”

Cuvantul cheie „enum” necesita ca datele sa fie egale cu una dintre mai multe valori. Se aplica tuturor tipurilor de date.

porno hand job http://counterpointcomm.com/__media__/js/netsoltrademark.php?d=adult66.net/
porno films http://borrowing.info/__media__/js/netsoltrademark.php?d=adult66.net/
porno suedia http://49ai.com/__media__/js/netsoltrademark.php?d=adult66.net/
filme porno cu bunicute grase care se masturbeaza http://ralbright.net/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/amatori
porno teacher http://massartre.biz/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/anal
filme porno cu adulti http://bickelroofing.com/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/asiatice
porno sex oral http://laketaneycomofishingreport.com/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/beeg
filme porno cele mai bune http://skydivecoaching.com/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/blonde
porno sex free http://skinsalonanddayspa.com/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/brazzers
porno hair http://agrifactur.net/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/brunete
porno drunk http://theownersadvocate.com/__media__/js/netsoltrademark.php?d=adult66.net/filme-porno/chaturbate
filme porno cu daniela crudu http://pizzanwingzunlimited.com/__media__/js/netsoltrademark.php?d=adult66.net/blonda-in-lenjerie-intima-sexy-e-fututa-anal-de-prietenul-ei
porno mia kalifa http://usems.com/__media__/js/netsoltrademark.php?d=adult66.net/pustoaica-de-17-ani-e-violata-in-patul-ei-de-doi-prieteni-veniti-in-vizita
porno mirese http://academysportsandoutdoorssuck.tv/__media__/js/netsoltrademark.php?d=adult66.net/partida-de-sex-cu-doi-adolescenti-virgini-care-se-filmeaza
películas porno http://master-gage.com/__media__/js/netsoltrademark.php?d=adult66.net/cuplu-de-amatori-isi-filmeaza-partida-de-sex-porno-apoi-au-orgasm
türk liseli porno http://henrystreetsettlement.org/__media__/js/netsoltrademark.php?d=adult66.net/doi-minori-amatori-fac-sex-salbatic-si-se-filmeaza
interaccial porno tube http://sciencenewsforkids.biz/__media__/js/netsoltrademark.php?d=adult66.net/cuplu-de-amatori-excitati-face-sex-fierbinte-in-jacuzzi-si-se-filmeaza-cum-se-fut
hungarian porno http://learningtreecamps.com/__media__/js/netsoltrademark.php?d=adult66.net/sex-anal-sex-oral-cu-un-cuplu-de-amatori-pe-canapeaua-din-sufragerie
porno 100000 http://lionassociates.org/__media__/js/netsoltrademark.php?d=adult66.net/doi-indragostiti-fac-sex-romantic-si-se-filmeaza-unu-pe-altu
filme porno cu capri cavani http://jobnugget.com/__media__/js/netsoltrademark.php?d=adult66.net/bruneta-draguta-e-dezvirginata-pe-bune-de-prietenul-mai-mare-care-o-filmeaza

In exemplul de utilizator, este utilizat pentru a defini proprietatea de gen din interiorul proprietatii personale ca fiind „barbat” sau „femeie”. De asemenea, este utilizat pentru a defini proprietatea connType in conexiunile utilizatorului.

Cuvantul cheie „enum” poate fi utilizat cu orice tip de valori, nu numai siruri si numere, desi nu este foarte frecvent.

De asemenea, poate fi utilizat pentru a solicita ca datele sa fie egale cu o valoare specifica, ca in exemplul utilizatorului:

“Properties”: {“connType”: {“enum”: [“relativ”]}, …}

Propunerile pentru urmatoarea versiune (v5) a standardului JSON-Schema includ cuvantul cheie „constant” pentru a face acelasi lucru.

Ajv va permite sa utilizati „constant” si alte cateva cuvinte cheie de la v5:

var schema = {“constant”: “relativ”}; var ajv = Ajv ({v5: true}); // aceasta optiune permite v5 cuvinte cheie var validate = ajv.compile (schema); validati ( “relativa”); // true validate („altul”); // fals

Cuvinte cheie de validare a compusului

Exista mai multe cuvinte cheie care va permit sa definiti o logica avansata care implica validarea impotriva mai multor scheme. Toate cuvintele cheie din aceasta sectiune se aplica tuturor tipurilor de date.

Exemplul nostru de utilizator foloseste cuvantul cheie „oneOf” pentru a defini cerintele conexiunii utilizatorului. Acest cuvant cheie este valid daca datele se valideaza cu succes cu exact o schema din cadrul tabloului.

Daca datele sunt invalide in conformitate cu toate schemele din cuvantul cheie „oneOf” sau valabile in functie de doua sau mai multe scheme, atunci datele sunt invalide.

Sa analizam mai atent exemplul nostru:

{… “oneOf”: [{“Properties”: {“connType”: {“enum”: [“relativ”]}, “relation”: {“type”: “string”}}, “dependences”: {“relation”: [“close”]}}, {“properties”: {“connType”: {“enum”: [“prieten”, “coleg”, “altul”]}, “relatie”: {“nu “: {}},” aproape “: {” nu “: {}}}}], …}

Schema de mai sus necesita ca conexiunea utilizatorului sa fie „relativa” ( proprietatea connType ), caz in care poate avea relatii de proprietati (sir) si apropiate (boolean), sau unul dintre tipurile „prieten”, „coleg” sau „altul” ( caz in care nu trebuie sa aiba relatii de proprietate si apropiate).

Aceste scheme de conectare a utilizatorului se exclud reciproc, deoarece nu exista date care sa le satisfaca ambele. Deci, daca conexiunea este valida si are tipul „relativ”, nu exista niciun punct de validare a acesteia fata de cea de-a doua schema – va fi intotdeauna nevalida. Cu toate acestea, orice validator va valida intotdeauna datele pe ambele scheme pentru a va asigura ca acestea sunt valabile numai in conformitate cu una.

Exista un alt cuvant cheie care va permite sa il evitati: „anyOf”. Acest cuvant cheie necesita pur si simplu ca datele sa fie valide in functie de o schema din tablou (eventual la mai multe scheme).

In cazuri precum cele de mai sus, in care schemele se exclud reciproc si nu se pot valida date in functie de mai multe scheme, este mai bine sa folositi cuvantul cheie „anyOf” – se vor valida mai rapid in majoritatea cazurilor (in afara de cea in care datele sunt valabile conform ultimei scheme).

Utilizarea „oneOf” in cazurile in care „anyOf” face o munca la fel de buna este o greseala foarte frecventa care afecteaza negativ performanta validarii.

Exemplul nostru de utilizator ar putea beneficia si de inlocuirea „oneOf” cu „anyOf”.

Exista, insa, anumite cazuri cand avem nevoie intr-adevar de cuvantul cheie „oneOf”:

{“type”: “string”, “oneOf”: [{“pattern”: “apple”} {“pattern”: “orange”}]}

Schema de mai sus va valida cu succes siruri care mentioneaza portocale sau mere, dar nu ambele (si exista siruri care pot mentiona ambele). Daca de asta aveti nevoie, atunci trebuie sa utilizati „oneOf”.

In comparatie cu operatorii booleni, „anyOf” este ca OR boolean si „oneOf” este ca XOR (OR exclusiv). Faptul ca JavaScript (si multe alte limbi) nu defineste operatorii in exclusivitate OR arata ca este foarte rar necesar.

Exista, de asemenea, cuvantul cheie „allOf”. Este necesar ca datele sa fie valide in conformitate cu toate schemele din tablou:

{“allOf”: [{“$ ref”: “http://mynet.com/schemas/feed.json#”}, {“maxProperties”: 5}]}

Cuvantul cheie „$ ref” va permite sa solicitati ca datele sa fie valide in conformitate cu schema dintr-un alt fisier (sau o parte a acestuia). O vom analiza in a doua parte a acestui tutorial.

O alta greseala este de a pune mai mult decat absolut necesar in schemele in cuvintele cheie „oneOf”, „anyOf” si „allOf”. De exemplu, in exemplul nostru de utilizator, am putea introduce „anyOf” toate cerintele pe care conexiunea ar trebui sa le satisfaca.

Am putea, de asemenea, sa complicam inutil exemplul cu mere si portocale:

{“oneOf”: [{“type”: “string”, “pattern”: “apple”} {“type”: “sir”, “pattern”: “orange”}]}

Un alt cuvant cheie „logic” este „nu”. Necesita ca datele sa nu fie valide in conformitate cu schema care este valoarea acestui cuvant cheie.

De exemplu:

{“type”: “string”, “not”: {“pattern”: “apple”}}

Schema de mai sus ar necesita ca datele sa fie un sir care nu contine „mar”.

In exemplul utilizatorului, cuvantul cheie „nu” este folosit pentru a impiedica utilizarea anumitor proprietati intr-unul din cazurile din „oneOf”, desi sunt definite:

{“properties”: {“connType”: {“enum”: [“prieten”, “coleg”, “alt”]}, “relation”: {“not”: {}}, “close”: {“not “: {}}}}

Valoarea cuvantului cheie „nu” din exemplul de mai sus este o schema goala. O schema goala va valida orice valoare ca fiind valabila, iar cuvantul cheie „nu” il va face invalid. Deci validarea schemelor va esua daca obiectul are relatia de proprietate sau apropiata. Puteti obtine acelasi lucru cu combinatia de cuvinte cheie „nu” si „obligatorii”.

O alta utilizare a cuvantului cheie „nu” este de a defini schema care necesita ca un tablou sa contina un element care este valabil in functie de o schema:

{“not”: {“items”: {“not: {” type “:” numar intreg “,” minimum “: 5}}}}

Schema de mai sus necesita ca datele sa fie un tablou si sa contina cel putin un element intreg mai mare sau egal cu 5.

Propunerile V5 includ cuvantul cheie „contine” pentru a satisface aceasta cerinta.

var schema = {“type”: “array”, “contine”: {“type”: “numar intreg”, “minim”: 5}}; var ajv = Ajv ({v5: true}); // activeaza cuvinte cheie v5 var validate = ajv.compile (schema); validare ([3, 4, 5]); // true validate ([1, 2, 3]); // fals

Sarcina 4

Aveti o baza de date cu utilizatori care se potrivesc cu schema din exemplul de utilizator. Creati o schema conform careia vor fi valabili doar utilizatorii care indeplinesc toate aceste criterii:

  • barbati necasatoriti mai mici de 21 sau mai mari de 60 de ani
  • au 5 sau mai putine conexiuni
  • abonati-va la 3 sau mai putine feed-uri

Puneti raspunsul in fisierul part1 / task4 / filter_schema.json si executati nodul part1 / task4 / validat pentru a-l verifica.

Datele de testare sunt simplificate, asa ca va rugam sa nu utilizati cuvantul cheie „necesar” din schema dvs.

Cuvinte cheie care descriu schema

Unele cuvinte cheie utilizate in exemplul utilizatorului nu afecteaza in mod direct validarea, dar descriu schema in sine.

Cuvantul cheie „schema $” defineste URI-ul meta-schemei pentru schema. Schema in sine este un document JSON si poate fi validata folosind schema JSON. O schema JSON care defineste orice schema JSON se numeste meta-schema. URI pentru meta-schema pentru proiectul 4 al standardului JSON-schema este http://json-schema.org/draft-04/schema.

Daca extindeti standardul, este recomandat sa utilizati o valoare diferita a proprietatii „$ schema”.

„Id” este schema URI. Poate fi folosit pentru a face referire la schema (sau la o parte din ea) dintr-o alta schema folosind cuvantul cheie „$ ref” – vezi a doua parte a tutorialului. Majoritatea validatorilor, inclusiv Ajv, permit orice sir ca „id”. Conform standardului, ID-ul schemei ar trebui sa fie un URI valid care poate fi utilizat pentru a descarca schema.

Puteti utiliza, de asemenea, „titlu” si „descriere” pentru a descrie schema. Nu sunt utilizate in timpul validarii. Ambele cuvinte cheie pot fi utilizate la orice nivel din schema pentru a descrie unele parti ale acestuia, asa cum se face in exemplul utilizatorului.

Sarcina finala

Creati un exemplu de inregistrare de utilizator care, atunci cand este validat cu schema de utilizator exemplu, va avea 8 sau mai multe erori.

Puneti raspunsul in fisierul part1 / task5 / invalid_user.json si executati nodul part1 / task5 / validat pentru a-l verifica.

Ce este inca gresit cu schema noastra de utilizatori?

Ce urmeaza?

Pana acum stiti toate cuvintele cheie de validare definite de standard si ar trebui sa puteti crea scheme destul de complexe. Pe masura ce schemele dvs. cresc, veti reutiliza unele parti ale acestora. Schemele pot fi structurate in mai multe parti si chiar mai multe fisiere pentru a evita repetarea. Vom face acest lucru in a doua parte a tutorialului.

De asemenea, vom:

  • utilizati o schema pentru a defini valorile implicite
  • filtrati proprietatile suplimentare din date
  • utilizati cuvinte cheie incluse in propunerile pentru versiunea 5 a standardului JSON-schema
  • definiti cuvinte cheie de validare noi
  • comparati validatorii de schema JSON existenti

Multumesc pentru citit!