Способы экономии трафика |
|
|---|---|
| PUT | Запись или замена данных по определенному пути, например fireblog/users/user1/<data>. |
| PATCH | Обновить некоторые ключи для определенного пути, не заменяя все данные. |
| POST | Добавление в список данных в базе данных Firebase. Каждый раз, когда мы отправляем запрос POST, клиент Firebase генерирует уникальный ключ, например fireblog/users/<unique-id>/<data>. |
| УДАЛИТЬ | Удаляет данные из указанной базы данных Firebase. |
Запись данных с помощью PUT
Базовая операция записи через REST API – PUT. Чтобы продемонстрировать сохранение данных, мы создадим приложение для ведения блогов с публикациями и пользователями. Все данные для нашего приложения будут храниться по пути fireblog в URL базы данных Firebase https://docs-examples.firebaseio.com/fireblog.
Для начала сохраним некоторые пользовательские данные в базе данных Firebase. Мы будем хранить данные каждого пользователя по уникальному имени пользователя, а также его полное имя и дату рождения. Поскольку у каждого пользователя будет уникальное имя, здесь имеет смысл использовать PUT вместо POST, так как у нас уже есть ключ и нам не нужно его создавать.
С помощью PUT можно записать в базу данных Firebase строку, число, логическое значение, массив или любой объект JSON. В этом случае мы передадим ему объект:
curl -X PUT -d '{
"alanisawesome": {
"name": "Alan Turing",
"birthday": "June 23, 1912"
}
}' 'https://docs-examples.firebaseio.com/fireblog/users.json'
Когда объект JSON сохраняется в базе данных, его свойства автоматически сопоставляются с дочерними местоположениями вложенным образом. Если мы перейдем к только что созданному узлу, то увидим значение "Alan Turing". Мы также можем сохранять данные непосредственно в дочернем местоположении:
curl -X PUT -d '"Alan Turing"' \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/name.json'
curl -X PUT -d '"June 23, 1912"' \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/birthday.json'
В обоих случаях (при записи значения одновременно с объектом и при записи в дочерние местоположения) в базу данных Firebase будут сохранены одни и те же данные:
{
"users": {
"alanisawesome": {
"date_of_birth": "June 23, 1912",
"full_name": "Alan Turing"
}
}
}
При успешном выполнении запроса будет получен код статуса HTTP 200 OK, а ответ будет содержать данные, которые мы записали в базу данных. В первом примере будет активировано только одно событие на клиентах, которые отслеживают данные, а во втором – два. Важно отметить, что если данные уже существовали по пути users, первый подход перезапишет их, а второй метод изменит только значение каждого отдельного дочернего узла, оставив другие дочерние узлы без изменений. PUT эквивалентно set() в нашем JavaScript SDK.
Обновление данных с помощью PATCH
С помощью запроса PATCH можно обновить определенные дочерние узлы в местоположении, не перезаписывая существующие данные. Добавим псевдоним Тьюринга в его пользовательские данные с помощью запроса PATCH:
curl -X PATCH -d '{
"nickname": "Alan The Machine"
}' \
'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'
Приведенный выше запрос запишет nickname в объект alanisawesome, не удаляя дочерние элементы name и birthday. Обратите внимание, что если бы мы отправили запрос PUT, то name и birthday были бы удалены, поскольку они не были включены в запрос. Данные в базе данных Firebase теперь выглядят следующим образом:
{
"users": {
"alanisawesome": {
"date_of_birth": "June 23, 1912",
"full_name": "Alan Turing",
"nickname": "Alan The Machine"
}
}
}
В случае успешного выполнения запроса будет возвращен код статуса HTTP 200 OK, а ответ будет содержать обновленные данные, записанные в базу данных.
Firebase также поддерживает многопутевые обновления. Это означает, что PATCH теперь может одновременно обновлять значения в нескольких местах базы данных Firebase. Эта мощная функция позволяет денормализовать данные. Используя многопутевые обновления, мы можем одновременно добавить псевдонимы Алану и Грейс:
curl -X PATCH -d '{
"alanisawesome/nickname": "Alan The Machine",
"gracehopper/nickname": "Amazing Grace"
}' \
'https://docs-examples.firebaseio.com/fireblog/users.json'
После этого обновления у Алана и Грейс появились псевдонимы:
{
"users": {
"alanisawesome": {
"date_of_birth": "June 23, 1912",
"full_name": "Alan Turing",
"nickname": "Alan The Machine"
},
"gracehop": {
"date_of_birth": "December 9, 1906",
"full_name": "Grace Hopper",
"nickname": "Amazing Grace"
}
}
}Обратите внимание, что попытка обновить объекты путем записи объектов с включенными путями приведет к другому поведению. Давайте посмотрим, что произойдет, если мы вместо этого попытаемся обновить Грейс и Алана следующим образом:
curl -X PATCH -d '{
"alanisawesome": {"nickname": "Alan The Machine"},
"gracehopper": {"nickname": "Amazing Grace"}
}' \
'https://docs-examples.firebaseio.com/fireblog/users.json'
Это приводит к другому поведению, а именно к перезаписи всего узла /fireblog/users:
{
"users": {
"alanisawesome": {
"nickname": "Alan The Machine"
},
"gracehop": {
"nickname": "Amazing Grace"
}
}
}Обновление данных с помощью условных запросов
Вы можете использовать условные запросы, эквивалентные транзакциям REST, для обновления данных в соответствии с их существующим состоянием. Например, если вы хотите увеличить счетчик голосов и убедиться, что он точно отражает несколько одновременных голосов, используйте условный запрос, чтобы записать новое значение в счетчик. Вместо двух записей, которые изменяют счетчик на одно и то же число, один из запросов на запись завершается ошибкой, и вы можете повторить запрос с новым значением.- Чтобы выполнить условный запрос в определенном местоположении, получите уникальный идентификатор текущих данных в этом местоположении или ETag. Если данные в этом месте изменяются, ETag также изменяется. Вы можете запросить ETag с помощью любого метода, кроме
PATCH. В примере ниже используется запросGET. Вызов ETag в заголовке возвращает ETag указанного местоположения в HTTP-ответе.curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
HTTP/1.1 200 OK Content-Length: 6 Content-Type: application/json; charset=utf-8 Access-Control-Allow-Origin: * ETag: [ETAG_VALUE] Cache-Control: no-cache 10 // Current value of the data at the specified location
- Включите возвращенный ETag в следующий запрос
PUTилиDELETE, чтобы обновить данные, которые соответствуют этому значению ETag. В нашем примере, чтобы обновить счетчик до 11 (на 1 больше, чем исходное полученное значение 10) и отклонить запрос, если значение больше не совпадает, используйте следующий код: Если значение данных в указанном местоположении по-прежнему равно 10, ETag в запросеcurl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
PUTсовпадает, запрос выполняется успешно и в базу данных записывается 11. Если местоположение больше не соответствует ETag (например, если другой пользователь записал новое значение в базу данных), запрос не выполняется и запись в местоположение не производится. Ответ содержит новое значение и ETag.HTTP/1.1 200 OK Content-Length: 6 Content-Type: application/json; charset=utf-8 Access-Control-Allow-Origin: * Cache-Control: no-cache 11 // New value of the data at the specified location, written by the conditional request
HTTP/1.1 412 Precondition Failed Content-Length: 6 Content-Type: application/json; charset=utf-8 Access-Control-Allow-Origin: * ETag: [ETAG_VALUE] Cache-Control: no-cache 12 // New value of the data at the specified location
- Используйте новую информацию, если решите повторить запрос. Realtime Database не повторяет автоматически условные запросы, которые не удалось выполнить. Однако вы можете использовать новое значение и ETag, чтобы создать новый условный запрос с информацией, возвращенной в ответе об ошибке.
Условные запросы на основе REST реализуют стандарт HTTP if-match. Однако у них есть следующие отличия:
- Для каждого запроса if-match можно указать только одно значение ETag.
- Хотя стандарт предполагает, что ETag должны возвращаться со всеми запросами, Realtime Database возвращает ETag только с запросами, включающими заголовок
X-Firebase-ETag. Это снижает сумму к оплате за стандартные запросы.
Условные запросы также могут выполняться медленнее, чем обычные запросы REST.
Сохранение списков данных
Чтобы создать уникальный ключ на основе временной метки для каждого дочернего элемента, добавленного в ссылку на базу данных Firebase, можно отправить запрос POST. Для пути users имеет смысл определить собственные ключи, поскольку у каждого пользователя уникальное имя. Но когда пользователи добавляют записи в блог, мы используем запрос POST, чтобы автоматически сгенерировать ключ для каждой записи:
curl -X POST -d '{
"author": "alanisawesome",
"title": "The Turing Machine"
}' 'https://docs-examples.firebaseio.com/fireblog/posts.json'
Теперь путь posts содержит следующие данные:
{
"posts": {
"-JSOpn9ZC54A4P4RoqVa": {
"author": "alanisawesome",
"title": "The Turing Machine"
}
}
}
Обратите внимание, что ключ -JSOpn9ZC54A4P4RoqVa был сгенерирован автоматически, поскольку мы использовали запрос POST. Если запрос выполнен успешно, будет возвращен код статуса HTTP 200 OK, а ответ будет содержать ключ добавленных данных:
{"name":"-JSOpn9ZC54A4P4RoqVa"}Удаление данных
Чтобы удалить данные из базы данных, мы можем отправить запрос DELETE с URL пути, из которого мы хотим удалить данные. Следующий запрос удалит пользователя Alan из пути users:
curl -X DELETE \ 'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'
При успешном выполнении запроса DELETE будет получен код статуса HTTP 200 OK с ответом, содержащим JSON null.
Параметры URI
При записи данных в базу данных REST API принимает следующие параметры URI:
аутентификация
Параметр запроса auth позволяет получить доступ к данным, защищенным Firebase Realtime Database Security Rules, и поддерживается всеми типами запросов. В качестве аргумента можно использовать секретный ключ приложения Firebase или токен аутентификации, о котором мы поговорим в разделе об авторизации пользователей. В примере ниже мы отправляем запрос POST с параметром auth, где CREDENTIAL – это секретный ключ приложения Firebase или токен аутентификации:
curl -X POST -d '{"Authenticated POST request"}' \
'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'
печать
Параметр print позволяет указать формат ответа из базы данных. Добавление print=pretty в запрос вернет данные в человекочитаемом формате. print=pretty поддерживается запросами GET, PUT, POST, PATCH и DELETE.
Чтобы подавить вывод с сервера при записи данных, мы можем добавить в запрос print=silent. Если запрос будет выполнен успешно, то ответ будет пустым и будет сопровождаться кодом статуса HTTP 204 No Content.
Параметр print=silent поддерживается в запросах GET, PUT, POST и PATCH.
Запись значений сервера
Значения сервера можно записать в местоположение, используя значение-плейсхолдер, которое является объектом с одним ключом ".sv". Значение для этого ключа – это тип значения сервера, которое мы хотим задать.
Например, чтобы установить временную метку при создании пользователя, можно сделать следующее:
curl -X PUT -d '{".sv": "timestamp"}' \
'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'
"timestamp" – единственное поддерживаемое значение сервера, которое представляет собой время в миллисекундах, прошедшее с начала эпохи UNIX.
Как повысить эффективность записи
Если мы записываем в базу данных большие объемы данных, мы можем использовать параметр print=silent, чтобы повысить производительность записи и снизить использование пропускной способности. При обычной записи сервер отвечает данными JSON, которые были записаны.
Если указано значение print=silent, сервер сразу же закрывает соединение после получения данных, что позволяет снизить нагрузку на сеть.
Если мы отправляем много запросов к базе данных, то можем повторно использовать HTTPS-подключение, отправив запрос Keep-Alive в HTTP-заголовке.
Условия возникновения ошибок
REST API возвращает коды ошибок в следующих случаях:
| Коды статуса HTTP | |
|---|---|
| 400 Недопустимый запрос |
Одна из следующих ошибок:
|
| 401: доступ запрещен |
Одна из следующих ошибок:
|
| 404 Не найдено | Указанная база данных Firebase не найдена. |
| 500 Внутренняя ошибка сервера | Сервер вернул ошибку. Подробные сведения приведены в сообщении об ошибке. |
| 503 Service Unavailable | Указанная база данных Firebase Realtime Database временно недоступна, поэтому запрос не был выполнен. |
Защита данных
В Firebase есть язык безопасности, который позволяет нам определять, у каких пользователей есть доступ на чтение и запись к различным узлам наших данных. Подробнее об этом рассказывается в Realtime Database Security Rules.
Теперь, когда мы рассмотрели сохранение данных, в следующем разделе мы можем узнать, как получить наши данные из базы данных Firebase через REST API.