HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>В вебе взаимодействие происходит по схеме клиент-сервер. Клиент отправляет запрос, а сервер отдает ответ.</p>
1 <p>В вебе взаимодействие происходит по схеме клиент-сервер. Клиент отправляет запрос, а сервер отдает ответ.</p>
2 <p>Обычно в запросах и ответах содержится информация о том, что именно клиент хочет от сервера. Например, при запросах на получение данных указывается, какие данные сервер должен вернуть. Чаще всего эти данные представляются в виде структур, при этом нам нужно передать их в текстовом виде. В этом случае разработчики используют сериализацию.</p>
2 <p>Обычно в запросах и ответах содержится информация о том, что именно клиент хочет от сервера. Например, при запросах на получение данных указывается, какие данные сервер должен вернуть. Чаще всего эти данные представляются в виде структур, при этом нам нужно передать их в текстовом виде. В этом случае разработчики используют сериализацию.</p>
3 <p>В этом уроке мы разберем формат сериализации данных - JSON. Мы рассмотрим, как сериализовать и десериализовать данные в JSON в Golang.</p>
3 <p>В этом уроке мы разберем формат сериализации данных - JSON. Мы рассмотрим, как сериализовать и десериализовать данные в JSON в Golang.</p>
4 <h2>Сериализация и десериализация в Golang</h2>
4 <h2>Сериализация и десериализация в Golang</h2>
5 <p>Представим, что нам нужно получить список пользователей. Клиент отправляет запрос GET /users, а сервер отдает ответ в виде списка пользователей. Список пользователей - это массив структур. Каждая структура содержит информацию о пользователе. Например, имя, фамилию, возраст, пол.</p>
5 <p>Представим, что нам нужно получить список пользователей. Клиент отправляет запрос GET /users, а сервер отдает ответ в виде списка пользователей. Список пользователей - это массив структур. Каждая структура содержит информацию о пользователе. Например, имя, фамилию, возраст, пол.</p>
6 <p>Мы знаем, что HTTP - это текстовый протокол, поэтому в запросе и ответе могут быть только текстовые данные. Поэтому нам нужно передать массив пользователей в текстовом виде. В этом нам поможет<strong>сериализация</strong>- процесс преобразования данных в строку. Сервер сериализует массив пользователей в строку и передает клиенту. Клиент может десериализовать строку обратно в массив структур пользователей.</p>
6 <p>Мы знаем, что HTTP - это текстовый протокол, поэтому в запросе и ответе могут быть только текстовые данные. Поэтому нам нужно передать массив пользователей в текстовом виде. В этом нам поможет<strong>сериализация</strong>- процесс преобразования данных в строку. Сервер сериализует массив пользователей в строку и передает клиенту. Клиент может десериализовать строку обратно в массив структур пользователей.</p>
7 <p>Десериализация - это процесс преобразования сериализованной строки обратно в данные, которое понимает приложение.</p>
7 <p>Десериализация - это процесс преобразования сериализованной строки обратно в данные, которое понимает приложение.</p>
8 <p>На схеме ниже показано, как происходит сериализация и десериализация данных при отправке HTTP-ответа от сервера к клиенту:</p>
8 <p>На схеме ниже показано, как происходит сериализация и десериализация данных при отправке HTTP-ответа от сервера к клиенту:</p>
9 <p>Сервер сериализует объекты пользователей в строку, отправляет это в теле HTTP-ответа, а клиент читает тело ответа и десериализует строку обратно в данные.</p>
9 <p>Сервер сериализует объекты пользователей в строку, отправляет это в теле HTTP-ответа, а клиент читает тело ответа и десериализует строку обратно в данные.</p>
10 <p>Существует множество протоколов сериализации данных. Они отличаются способами преобразования данных в строку и форматами сериализованной строки. Наиболее популярные протоколы сериализации данных: JSON, XML, YAML, MessagePack и Protocol Buffers.</p>
10 <p>Существует множество протоколов сериализации данных. Они отличаются способами преобразования данных в строку и форматами сериализованной строки. Наиболее популярные протоколы сериализации данных: JSON, XML, YAML, MessagePack и Protocol Buffers.</p>
11 <p>В этом курсе мы разберем самый популярный протокол сериализации данных -<strong>JSON</strong>. У него есть следующие преимущества:</p>
11 <p>В этом курсе мы разберем самый популярный протокол сериализации данных -<strong>JSON</strong>. У него есть следующие преимущества:</p>
12 <ul><li>Простой в изучении, чтении и понимании</li>
12 <ul><li>Простой в изучении, чтении и понимании</li>
13 <li>Поддерживается большинством языков программирования</li>
13 <li>Поддерживается большинством языков программирования</li>
14 <li>Формат достаточно компактный по сравнению с широко используемым в прошлом XML</li>
14 <li>Формат достаточно компактный по сравнению с широко используемым в прошлом XML</li>
15 </ul><p>Перед тем, как продолжить, ознакомьтесь с этим форматом сериализации в<a>документации</a>.</p>
15 </ul><p>Перед тем, как продолжить, ознакомьтесь с этим форматом сериализации в<a>документации</a>.</p>
16 <p>Для сериализации и десериализации данных в JSON используется стандартная библиотека. Для этого в ней есть две функции:</p>
16 <p>Для сериализации и десериализации данных в JSON используется стандартная библиотека. Для этого в ней есть две функции:</p>
17 <ul><li>json.Marshal() - сериализует данные в JSON</li>
17 <ul><li>json.Marshal() - сериализует данные в JSON</li>
18 <li>json.Unmarshal() - десериализует данные из JSON</li>
18 <li>json.Unmarshal() - десериализует данные из JSON</li>
19 </ul><p>Так в GO происходит сериализация и десериализация структуры:</p>
19 </ul><p>Так в GO происходит сериализация и десериализация структуры:</p>
20 <p>При запуске программы видим вывод:</p>
20 <p>При запуске программы видим вывод:</p>
21 <p>В данном Go-приложении мы преобразовали объект пользователя<em>User</em>в JSON-строку и обратно. В результате мы получили ту же структуру<em>User</em>, но с пустым полем<em>password</em>, потому что указали, что это приватное поле. Если бы мы отправили такую JSON-строку по сети другому веб-приложению, то оно смогло бы восстановить изначальный объект<em>User</em>без поля<em>password</em>.</p>
21 <p>В данном Go-приложении мы преобразовали объект пользователя<em>User</em>в JSON-строку и обратно. В результате мы получили ту же структуру<em>User</em>, но с пустым полем<em>password</em>, потому что указали, что это приватное поле. Если бы мы отправили такую JSON-строку по сети другому веб-приложению, то оно смогло бы восстановить изначальный объект<em>User</em>без поля<em>password</em>.</p>
22 <p>Важные моменты работы с JSON в Go:</p>
22 <p>Важные моменты работы с JSON в Go:</p>
23 <ul><li><p>В структуре сериализуются только публичные свойства, которые написаны с заглавной буквы. В нашем примере свойство password - приватное, поэтому оно не попало в JSON-строку. Такое же правило действует и на десериализацию. Если мы добавим значение password в JSON-строку, то это значение все равно не попадет в десериализованную структуру</p>
23 <ul><li><p>В структуре сериализуются только публичные свойства, которые написаны с заглавной буквы. В нашем примере свойство password - приватное, поэтому оно не попало в JSON-строку. Такое же правило действует и на десериализацию. Если мы добавим значение password в JSON-строку, то это значение все равно не попадет в десериализованную структуру</p>
24 </li>
24 </li>
25 <li><p>В JSON-строке можно указывать название свойства, которое будет отличаться от названия свойства в структуре. Для этого используется тег json:"". В нашем примере мы указали тег для свойства ID в виде json:"id". Так можно указывать, в каком виде должно называться свойство в JSON-строке в зависимости от соглашений в проекте</p>
25 <li><p>В JSON-строке можно указывать название свойства, которое будет отличаться от названия свойства в структуре. Для этого используется тег json:"". В нашем примере мы указали тег для свойства ID в виде json:"id". Так можно указывать, в каком виде должно называться свойство в JSON-строке в зависимости от соглашений в проекте</p>
26 </li>
26 </li>
27 <li><p>При описании тега json:"" можно указать опцию omitempty. Эта опция говорит о том, что если значение свойства является нулевым, то это поле не нужно включать в сериализованную строку</p>
27 <li><p>При описании тега json:"" можно указать опцию omitempty. Эта опция говорит о том, что если значение свойства является нулевым, то это поле не нужно включать в сериализованную строку</p>
28 </li>
28 </li>
29 </ul><p>Мы научились работать с JSON в Golang, теперь рассмотрим, как использовать этот формат в веб-приложениях.</p>
29 </ul><p>Мы научились работать с JSON в Golang, теперь рассмотрим, как использовать этот формат в веб-приложениях.</p>
30 <h2>JSON в веб-приложении</h2>
30 <h2>JSON в веб-приложении</h2>
31 <p>В веб-приложениях JSON используется, чтобы обменивать данные между клиентом и сервером. Клиент может отправлять HTTP-запрос с телом запроса в формате JSON, а сервер может возвращать HTTP-ответ с телом в формате JSON.</p>
31 <p>В веб-приложениях JSON используется, чтобы обменивать данные между клиентом и сервером. Клиент может отправлять HTTP-запрос с телом запроса в формате JSON, а сервер может возвращать HTTP-ответ с телом в формате JSON.</p>
32 <p>Веб-клиент отправляет JSON в теле запроса в случае, когда нужно изменить состояние чего-либо. Например, если пользователь заполнил форму регистрации, то веб-клиент отправит JSON с данными формы на сервер. Сервер в этом случае сохранит нового пользователя в базе данных.</p>
32 <p>Веб-клиент отправляет JSON в теле запроса в случае, когда нужно изменить состояние чего-либо. Например, если пользователь заполнил форму регистрации, то веб-клиент отправит JSON с данными формы на сервер. Сервер в этом случае сохранит нового пользователя в базе данных.</p>
33 <p>Сервер возвращает ответ с JSON, когда клиент запрашивает данные. Например, клиент запросил список курсов на Хекслете, и сервер вернул JSON массив структур курсов.</p>
33 <p>Сервер возвращает ответ с JSON, когда клиент запрашивает данные. Например, клиент запросил список курсов на Хекслете, и сервер вернул JSON массив структур курсов.</p>
34 <p>Реализуем эти концепции на примере Fiber веб-приложения. В Fiber работа с JSON происходит через контекст запроса c *fiber.Ctx. Для этого есть два метода:</p>
34 <p>Реализуем эти концепции на примере Fiber веб-приложения. В Fiber работа с JSON происходит через контекст запроса c *fiber.Ctx. Для этого есть два метода:</p>
35 <ul><li>c.BodyParser() - преобразует JSON-тело запроса в объект</li>
35 <ul><li>c.BodyParser() - преобразует JSON-тело запроса в объект</li>
36 <li>c.JSON() - отправляет JSON-строку в теле ответа</li>
36 <li>c.JSON() - отправляет JSON-строку в теле ответа</li>
37 </ul><p>Реализуем веб-приложение для сохранения логов, в котором отправим JSON в теле запроса и получим JSON в теле ответа.</p>
37 </ul><p>Реализуем веб-приложение для сохранения логов, в котором отправим JSON в теле запроса и получим JSON в теле ответа.</p>
38 <p>В приложении будет единственный метод /logs, который будет принимать POST-запросы на сохранение записи. В теле запроса передается структура одной записи логов. В ответе веб-приложение возвращает структуру с идентификатором сохраненной записи:</p>
38 <p>В приложении будет единственный метод /logs, который будет принимать POST-запросы на сохранение записи. В теле запроса передается структура одной записи логов. В ответе веб-приложение возвращает структуру с идентификатором сохраненной записи:</p>
39 <p>Запускаем веб-приложение и отправляем запрос на сохранение тестовой записи:</p>
39 <p>Запускаем веб-приложение и отправляем запрос на сохранение тестовой записи:</p>
40 <p>В ответ получаем идентификатор:</p>
40 <p>В ответ получаем идентификатор:</p>
41 <p>В данном веб-приложении мы описали структуры запроса и ответа с публичными свойствами и JSON-тегами. Благодаря этому, мы смогли использовать структуру запроса CreateLogEntryRequest в методе c.BodyParser(), чтобы десериализовать тела запроса из JSON. Также мы использовали структуру ответа CreateLogEntryResponse в методе c.JSON(), чтобы сериализовать тела ответа в JSON.</p>
41 <p>В данном веб-приложении мы описали структуры запроса и ответа с публичными свойствами и JSON-тегами. Благодаря этому, мы смогли использовать структуру запроса CreateLogEntryRequest в методе c.BodyParser(), чтобы десериализовать тела запроса из JSON. Также мы использовали структуру ответа CreateLogEntryResponse в методе c.JSON(), чтобы сериализовать тела ответа в JSON.</p>
42 <h2>Выводы</h2>
42 <h2>Выводы</h2>
43 <p>В этом уроке мы изучили, что такое сериализация - процесс преобразования структур данных в строку. И десериализация - процесс преобразования сериализованной строки обратно в данные.</p>
43 <p>В этом уроке мы изучили, что такое сериализация - процесс преобразования структур данных в строку. И десериализация - процесс преобразования сериализованной строки обратно в данные.</p>
44 <p>Еще мы разобрали самый популярный формат сериализации данных - JSON, так как он простой в генерации и чтении по сравнению с аналогами.</p>
44 <p>Еще мы разобрали самый популярный формат сериализации данных - JSON, так как он простой в генерации и чтении по сравнению с аналогами.</p>
45 <p>Напомним еще несколько важных моментов из урока:</p>
45 <p>Напомним еще несколько важных моментов из урока:</p>
46 <ul><li>В Go у структур сериализуются только публичные поля</li>
46 <ul><li>В Go у структур сериализуются только публичные поля</li>
47 <li>В фреймворке Fiber есть функция c.BodyParser(), которая позволяет десериализовать JSON тело запроса в структуру</li>
47 <li>В фреймворке Fiber есть функция c.BodyParser(), которая позволяет десериализовать JSON тело запроса в структуру</li>
48 <li>В фреймворке Fiber есть функция c.JSON(), которая позволяет сериализовать структуру тела ответа в JSON</li>
48 <li>В фреймворке Fiber есть функция c.JSON(), которая позволяет сериализовать структуру тела ответа в JSON</li>
49 </ul>
49 </ul>