JSON-LD стремится объединить возможности самоописываемой гипермедиа с простотой использования JSON. Включая ссылки на данные, JSON-LD позволяет разработчикам добавлять семантическую информацию в типичный API JSON. Давайте посмотрим на это мощное расширение JSON.
Что такое JSON-LD?
JSON-LD (нотация объектов JavaScript для связанных данных) расширяет формат JSON, включив в него информацию о связывании. Расширение имеет широкий спектр применения: от графиков знаний до SEO. Одним из наиболее интересных вариантов использования JSON-LD является приближение API-интерфейсов на основе JSON к первоначальному видению REST, где гипермедийные документы имеют самоописание и поддерживают слабую связь между сервером и клиентом.
Большая проблема с типичными API-интерфейсами JSON заключается в том, что они создают сильную связь между клиентом и сервером. Клиент знает, где живут активы и их взаимоотношения в сервисах. Жесткое кодирование URL-адресов, как это делает JSON, создает уязвимость для клиентов. Это противоречит идеалу REST, согласно которому активы сами сообщают клиенту, где найти соответствующую информацию.
На высоком уровне JSON-LD делает JSON членом семантической сети. он же Веб 3.0. Семантическая сеть — это идея того, как сделать сеть более значимой. Он стремится заменить нынешнюю систему произвольных мест взаимосвязанной сетью связанных активов. Это большой проект, многогранный. В нашем обсуждении мы сосредоточимся на практическом опыте работы с JSON-LD, создав приложение, которое демонстрирует концепцию семантической сети в настройке клиент-сервер.
JSON-LD в клиент-серверном приложении
Чтобы понять, как работает JSON-LD, мы создадим небольшое клиент-серверное приложение, которое обслуживает JSON-LD с сервера Node.js, а также простой пользовательский интерфейс, который позволит нам перемещаться по структуре. Мы будем использовать взаимосвязанный набор данных, описывающих музыку. Мы сможем начать со списка альбомов (всего пару, чтобы было проще), а затем щелкнуть название альбома, чтобы просмотреть простые данные о нем. Мы также сможем нажать на название песни и увидеть, кто ее авторы.
Давайте начнем с отображения наших альбомов по имени и предоставления пользователю возможности щелкнуть по ним для получения дополнительной информации. Вместо жесткого кодирования URL-адреса, по которому мы сохранили сведения об альбоме, мы будем использовать JSON-LD для определения URL-адреса в самом JSON в качестве идентификатора. Эта установка уводит нас от использования числа в качестве идентификатора к использованию фактического местоположения.
Листинг 1. Простая конечная точка JSON-LD (server.js)
const express = require('express');
const app = express();
const albumsData = [
{
"@id": "/music/albums/1",
"name": "Abbey Road",
"songs": [
{
"@id": "/music/songs/1",
"name": "Here Comes the Sun",
"songwriters": ["George Harrison"]
}
]
},
{
"@id": "/music/albums/2",
"name": "Let It Be",
"songs": [
{
"@id": "/music/songs/2",
"name": "Let It Be",
"songwriters": ["John Lennon", "Paul McCartney"]
}
]
}
];
// Define a route to serve album data
app.get('/music/albums', (req, res) => {
res.json(albumsData);
});
app.get('/music/albums/:albumId', (req, res) => {
const albumId = req.params.albumId;
const album = albumsData.find(album => album["@id"] === `/music/albums/${albumId}`);
if (album) {
res.json(album);
} else {
res.status(404).json({ error: "Album not found" });
}
});
app.use(express.static('public'));
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
Данные, выдаваемые конечной точкой, представляют собой типичный JSON, за исключением того, что они имеют @id
свойство. Свойства, начинающиеся со знака адреса (@
символ) являются специфичными для JSON-LD. В этом случае мы предоставляем реальную ссылку, которую клиент может использовать. Обратите внимание, что в идеале Web 3.0 ссылки должны быть абсолютными, чтобы помочь сформировать универсальный граф знаний. Мы используем относительные URL-адреса в целях разработки.
В типичном JSON API у нас есть поле идентификатора и целое число для значения. Затем клиент формирует URL-адрес на основе этого идентификатора. В этом случае клиент фактически может использовать поле идентификатора как есть. Сервер обрабатывает такие URL-адреса по мере необходимости в /music/albums/:albumId
конечная точка. (Реальная конечная точка потребует более сложной обработки.)
Простой клиент для этого API будет выглядеть, как в листинге 2.
Листинг 2. Простой клиент JSON-LD (public/index.html)
<!DOCTYPE html>
<html>
<head>
<title>JSON-LD Client</title>
</head>
<body>
<h1>Albums</h1>
<ul id="album-list"></ul>
<div id="album-details"></div>
<script>
const albumList = document.getElementById("album-list");
const albumDetails = document.getElementById("album-details");
// Function to fetch and display albums
function fetchAlbums() {
fetch("/music/albums")
.then(response => response.json())
.then(albums => {
albums.forEach(album => {
const listItem = document.createElement("li");
listItem.innerHTML = `<a href="#" data-album-id="${album["@id"]}">${album.name}</a>`;
albumList.appendChild(listItem);
});
});
}
// Function to fetch and display album details
function fetchAlbumDetails(albumId) {
fetch(albumId)
.then(response => response.json())
.then(album => {
const albumInfo = `
<h2>${album.name}</h2>
<h3>Songs</h3>
<ul>
${album.songs.map(song => `<li><a href="#" data-song-id="${song["@id"]}">${song.name}</a></li>`).join("")}
</ul>
`;
albumDetails.innerHTML = albumInfo;
});
}
// Event listener for album links
albumList.addEventListener("click", (event) => {
if (event.target.tagName === "A") {
const albumId = event.target.getAttribute("data-album-id");
fetchAlbumDetails(albumId);
}
});
// Event listener for song links
albumDetails.addEventListener("click", (event) => {
if (event.target.tagName === "A") {
const songId = event.target.getAttribute("data-song-id");
alert("You clicked on song with ID: " + songId);
}
});
// Initialize the client by fetching and displaying albums
fetchAlbums();
</script>
</body>
</html>
Листинг 2 представляет собой сильно упрощенный пример, призванный подчеркнуть основную мысль: клиент может работать со ссылками обычным способом, просто отправляя запросы на выборку по адресу. @id
поля. Это первый шаг к обобщению клиентов, чтобы они не знали о структуре API службы.
Поля @Context и @Type
JSON-LD — это гораздо больше, и @context
и @type
поля играют большую роль в формировании семантических документов. Существует несколько общедоступных репозиториев для информации о контексте и типах, которые вы можете использовать, включая Schema.org, пространства имен XML и контексты JSON-LD.
Schema.org — это обширный консорциум поисковых систем. Пространства имен XML являются древними и знакомыми, а также более обширными. Контексты JSON-LD призваны быть более простыми и в то же время всеобъемлющими. Приложение также может определять свои собственные типы и использовать сочетание источников определений.
Основная идея для @context
и @type
Поля — это позволить документу JSON описывать его содержимое в (более) универсальном формате.
- свойство @context определяет пространство имен для документа. Он действует как сопоставление между терминами, используемыми в документе, и их определениями, делая значение данных более понятным для людей и машин.
- свойство @type позволяет нам определить тип сущностей или элементов данных. Этот тип помогает классифицировать данные, упрощая их интерпретацию.
В листинге 3 мы видим, как использовать файл Schema.org. @context
и определения, такие как MusicComposition @type
.
Листинг 3. Использование @context и @type
const albumsData = [
{
"@context": {
"music": "http://schema.org/",
},
"@type": "music:MusicAlbum",
"@id": "/music/albums/1",
"name": "Abbey Road",
"songs": [
{
"@type": "music:MusicComposition",
"@id": "/music/songs/1",
"name": "Here Comes the Sun",
"songwriters": [
{
"@type": "music:MusicGroup",
"name": "The Beatles",
}
]
}
]
},
{
"@context": {
"music": "http://schema.org/",
},
"@type": "music:MusicAlbum",
"@id": "/music/albums/2",
"name": "Let It Be",
"songs": [
{
"@type": "music:MusicComposition",
"@id": "/music/songs/2",
"name": "Let It Be",
"songwriters": [
{
"@type": "music:MusicGroup",
"name": "The Beatles",
}
]
}
]
}
];
Мы использовали определение, размещенное на сайте Schema.org, и дали ему название «музыка». Определение действует как пространство имен, когда мы присваиваем типы нашим элементам данных; в этом случае, music:MusicComposition
и music:MusicGroup
.
Теперь клиент может использовать @context
и @type
данные. В качестве простого примера в нашем приложении мы могли бы принимать решения о том, как отображать данные, на основе этих полей. Обратите внимание, что приложение на самом деле ничего не получает с сайта Schema.org; он использует его только как уникальное пространство имен и как ссылку для структурирования своих собственных данных.
Развернуть и сжать
В отношении @type
стоит упомянуть понятие расширять и сжимать. Расширение обеспечивает более подробное представление, тогда как сжатие обеспечивает более жесткий синтаксис. Развернуть @type
как наш music:MusicAlbum
и разверните его до http://schema.org/MusicAlbum. Компакт сделает обратное.
Такие библиотеки, как jsonls.js, поддерживают эти и другие операции, например преобразование в формат RDF.
Заключение
JSON-LD сыграет важную роль в обеспечении большей реализации идеалов семантической сети для разработчиков. JSON — это лингва-франка форматов API, а JSON-LD обеспечивает удобную точку входа для добавления к нему семантических метаданных.
Дальше читайте это:
- Облачные вычисления больше не являются пустяком
- Что такое генеративный ИИ? Искусственный интеллект, который создает
- Программирование с помощью ИИ: советы и лучшие практики от разработчиков
- Python пытается удалить GIL и повысить параллелизм
- 7 причин, по которым Java по-прежнему хороша
- Война за лицензирование открытого исходного кода окончена