Skąd bierze się nieczytelny JSON
Większość JSON-a, z którym spotykasz się w praktyce, została napisana przez program dla innego programu, więc przychodzi jako jedna długa linia: odpowiedź API skopiowana z karty sieci w przeglądarce, ładunek webhooka w pliku logu, wartość konfiguracji przechowywana w kolumnie bazy danych. Czytanie jednej linii liczącej 4000 znaków w poszukiwaniu jednego zagnieżdżonego pola jest powolne i podatne na błędy. Ładne formatowanie umieszcza każdy klucz w osobnej linii i wcina każdy poziom, więc strukturę widać na pierwszy rzut oka.
Odwrotna sytuacja jest równie częsta. Zanim wkleisz JSON do zmiennej środowiskowej, parametru zapytania, danych testowych czy wiadomości na czacie, często chcesz, by był jak najbardziej zwarty. Minifikacja usuwa każdą spację i złamanie linii poza wartościami tekstowymi; typowy plik konfiguracyjny z wcięciami kurczy się o 20–40 procent, w zależności od głębokości zagnieżdżenia.
Co formatowanie robi z Twoimi danymi
Dane wejściowe są parsowane natywnym parserem JSON przeglądarki i zapisywane z powrotem z wybranym wcięciem: 2 spacje, 4 spacje lub tabulator. Minifikacja idzie tą samą ścieżką, ale bez żadnego wcięcia. Ponieważ dokument jest odbudowywany ze sparsowanej wartości, a nie edytowany jako tekst, kilka szczegółów może się zmienić i warto wiedzieć, które:
- Zapis liczb jest normalizowany.
1.0staje się1,1e3staje się1000, a-0staje się0. Wartość jest ta sama, zapis nie. - Bardzo duże liczby całkowite tracą precyzję. JavaScript przechowuje liczby jako 64-bitowe liczby zmiennoprzecinkowe, które są dokładne tylko do 9 007 199 254 740 991. 19-cyfrowy identyfikator, taki jak
12345678901234567890, wraca jako12345678901234567000. Jeśli Twoje dane zawierają identyfikatory w stylu Snowflake, bigint z bazy danych albo kwoty płatności w groszach w tej skali, porównaj wynik przed użyciem. - Sekwencje Unicode są dekodowane.
"caf\u00e9"jest zapisywane z powrotem jako"café". Oba zapisy są poprawnym JSON-em i oznaczają ten sam ciąg. - Zduplikowane klucze się scalają. Jeśli obiekt zawiera ten sam klucz dwa razy, przetrwa tylko ostatnia wartość. Standard JSON pozostawia duplikaty niezdefiniowane, a większość parserów zachowuje się właśnie tak.
- Klucze wyglądające jak liczby całkowite przechodzą na początek. Klucze przypominające nieujemne liczby całkowite, takie jak
"2"czy"10", są umieszczane jako pierwsze w kolejności rosnącej, przed wszystkimi innymi kluczami. To reguła obiektów JavaScript, a nie JSON. Zwykłe klucze tekstowe zachowują pierwotną kolejność.
Nic z tego nie ma znaczenia dla typowych odpowiedzi API, ale ma, jeśli zamierzasz zatwierdzić sformatowany plik i chcesz minimalnego diffa.
Jak czytać pozycję błędu
Gdy parsowanie się nie udaje, narzędzie uruchamia własny mały skaner, który znajduje pierwszy znak uniemożliwiający kontynuację poprawnego dokumentu, i zgłasza go jako linię i kolumnę.
Zgłoszone miejsce to punkt, w którym parser się poddał, co nie zawsze jest miejscem, gdzie popełniono błąd:
- Przecinek na końcu w
[1, 2, ]jest zgłaszany przy nawiasie zamykającym, bo tam oczekiwano wartości. - Brakujący przecinek między dwiema właściwościami jest zgłaszany na początku drugiego klucza.
- Brakujący nawias klamrowy lub kwadratowy zamykający jest zgłaszany na samym końcu danych wejściowych, czasem setki linii poniżej prawdziwego problemu. Szukaj ostatniego otwartego obiektu lub tablicy.
- Ciąg bez cudzysłowu zamykającego jest zgłaszany na końcu swojej linii, bo surowe złamanie linii nie jest dozwolone wewnątrz ciągu JSON. Ta sama pozycja pojawia się przy wielowierszowym tekście wklejonym do wartości; złamania linii trzeba tam zapisywać jako
\n.
Jeśli dane wejściowe to w rzeczywistości nie JSON, lecz literał obiektu JavaScript, YAML albo słownik Pythona wypisany z pojedynczymi cudzysłowami, błąd pojawi się w pierwszej lub drugiej linii. Te formaty wyglądają podobnie, ale nie są zamienne.
Wybór wcięcia
- 2 spacje to ustawienie domyślne w większości narzędzi JavaScript, plikach
package.jsoni wielu przewodnikach stylu. Dzięki temu głęboko zagnieżdżone dane nie uciekają za prawą krawędź ekranu. - 4 spacje odpowiadają temu, co daje
json.dumps(indent=4)w Pythonie, i łatwiej się je czyta przy płytkich dokumentach. - Tabulator pozwala każdemu czytelnikowi wybrać szerokość wizualną w swoim edytorze i daje nieco mniejsze pliki niż 4 spacje.
W przypadku plików w repozytorium dopasuj się do tego, czego projekt już używa; mieszanie stylów sprawia, że każdy diff jest zaszumiony.
Co dalej ze sformatowanymi danymi
Gdy struktura jest czytelna, inne zadania stają się łatwiejsze. Aby rozłożyć tablicę rekordów w arkuszu kalkulacyjnym, przekonwertuj ją narzędziem JSON na CSV. Aby zobaczyć, co dokładnie zmieniło się między dwiema wersjami ładunku, sformatuj obie z tym samym wcięciem i porównaj je w narzędziu porównaj teksty; identyczne formatowanie oznacza, że diff pokazuje tylko prawdziwe zmiany. Wszystko dzieje się na stronie, więc tokeny i dane osobowe w ładunku zostają na Twoim urządzeniu.