JavaScript · API · Средний

Профиль пользователя

5 задач

Читайте и обновляйте профиль с помощью GET, PATCH и PUT-запросов.

GET, PATCH и PUT — когда использовать каждый

#
Все три метода используют один эндпоинт `/api/users/profile/`, все требуют Authorization: ``` GET /api/users/profile/ Прочитать текущий профиль PATCH /api/users/profile/ Частичное обновление — изменяются только отправленные поля PUT /api/users/profile/ Полная замена — необходимы все поля ``` Поля профиля: ```javascript { id: 1, username: "alice42", email: "[email protected]", first_name: "Alice", last_name: "Smith", phone_number: "+1234567890", image: null } ``` **PATCH** — точечное обновление. Отправляйте только то, что хотите изменить: ```javascript // Изменяется только first_name — всё остальное остаётся без изменений await fetch(`${BASE_URL}/api/users/profile/`, { method: 'PATCH', headers, body: JSON.stringify({ first_name: 'Alicia' }), }).then(r => r.json()); ``` **PUT** — полная замена. Необходимо отправить все поля, или пропущенные будут очищены: ```javascript // Необходимо включить все поля await fetch(`${BASE_URL}/api/users/profile/`, { method: 'PUT', headers, body: JSON.stringify({ username: 'alice42', email: '[email protected]', first_name: 'Alicia', last_name: 'Smith', phone_number: '+1234567890', }), }); ``` Используйте PATCH для большинства обновлений — это безопаснее, так как не затрагивает поля, которые вы не отправили.

Чтение и обновление профиля

#
Читаем профиль, обновляем одно поле через PATCH, проверяем, затем заменяем все поля через PUT: ```javascript const BASE_URL = 'https://apilearn.tukas.dev'; async function main() { const { token } = await fetch(`${BASE_URL}/api/auth/token/`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' }), }).then(r => r.json()); const headers = { 'Authorization': `Token ${token}`, 'Content-Type': 'application/json', }; const PROFILE_URL = `${BASE_URL}/api/users/profile/`; // Читаем текущий профиль const profile = await fetch(PROFILE_URL, { headers }).then(r => r.json()); console.log('Имя:', profile.first_name); console.log('Email:', profile.email); // PATCH — изменяем только first_name const patched = await fetch(PROFILE_URL, { method: 'PATCH', headers, body: JSON.stringify({ first_name: 'Alicia' }), }).then(r => r.json()); console.log('Новое имя:', patched.first_name); // Alicia console.log('Email не изменился:', patched.email); // тот же // PUT — заменяем все поля const updated = await fetch(PROFILE_URL, { method: 'PUT', headers, body: JSON.stringify({ username: profile.username, email: '[email protected]', first_name: 'Alicia', last_name: profile.last_name || '', phone_number: profile.phone_number || '', }), }).then(r => r.json()); console.log('Email после PUT:', updated.email); } main(); ``` Переиспользуемый помощник обновления: ```javascript async function updateProfile(headers, fields) { return fetch(`${BASE_URL}/api/users/profile/`, { method: 'PATCH', headers, body: JSON.stringify(fields), }).then(r => r.json()); } const result = await updateProfile(headers, { first_name: 'Bob', phone_number: '+9998887777' }); console.log(result.first_name); ```

Справочник эндпоинта профиля

#
**Эндпоинт** ``` GET /api/users/profile/ Прочитать профиль → 200 + объект профиля PATCH /api/users/profile/ Частичное обновление → 200 + обновлённый профиль PUT /api/users/profile/ Полная замена → 200 + обновлённый профиль ``` **Поля профиля** ``` id number Неизменяемый id пользователя username string Имя для входа (уникальное) email string first_name string last_name string phone_number string Формат: +1234567890 image string URL или null ``` **PATCH vs PUT** ``` PATCH Отправлять только изменённые поля Безопасно — другие поля не затрагиваются PUT Отправлять все поля Отсутствующие поля будут очищены ``` **Безопасный паттерн PUT — сначала прочитать, затем отправить все** ```javascript const current = await fetch(PROFILE_URL, { headers }).then(r => r.json()); await fetch(PROFILE_URL, { method: 'PUT', headers, body: JSON.stringify({ ...current, email: '[email protected]' }), }); ```
01

Прочитать профиль

#

Авторизуйтесь и отправьте GET `/api/users/profile/`. Выведите `username` и `email`.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // GET /api/users/profile/ и вывести username и email
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const { token } = await fetch(`${BASE_URL}/api/auth/token/`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' }),
  }).then(r => r.json());

  const profile = await fetch(`${BASE_URL}/api/users/profile/`, {
    headers: { 'Authorization': `Token ${token}` },
  }).then(r => r.json());

  console.log(profile.username);
  console.log(profile.email);
}

main();
02

Обновить имя через PATCH

#

Прочитайте текущий профиль, затем обновите `first_name` через PATCH. Выведите новое `first_name` и подтвердите, что `email` не изменился.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // 1. авторизоваться
  // 2. прочитать профиль
  // 3. PATCH first_name
  // 4. вывести новое first_name и подтвердить что email не изменился
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const { token } = await fetch(`${BASE_URL}/api/auth/token/`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' }),
  }).then(r => r.json());

  const headers = {
    'Authorization': `Token ${token}`,
    'Content-Type': 'application/json',
  };
  const PROFILE_URL = `${BASE_URL}/api/users/profile/`;

  const before = await fetch(PROFILE_URL, { headers }).then(r => r.json());
  console.log('Before:', before.first_name);

  const after = await fetch(PROFILE_URL, {
    method: 'PATCH', headers,
    body: JSON.stringify({ first_name: 'Updated' }),
  }).then(r => r.json());

  console.log('After:', after.first_name);
  console.log('Email unchanged:', after.email === before.email);
}

main();
03

Обновить несколько полей сразу

#

За один PATCH-запрос обновите `first_name`, `last_name` и `phone_number`. Выведите все три обновлённых значения.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // PATCH 3 поля сразу
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const { token } = await fetch(`${BASE_URL}/api/auth/token/`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' }),
  }).then(r => r.json());

  const headers = {
    'Authorization': `Token ${token}`,
    'Content-Type': 'application/json',
  };

  const updated = await fetch(`${BASE_URL}/api/users/profile/`, {
    method: 'PATCH', headers,
    body: JSON.stringify({
      first_name: 'Test',
      last_name: 'User',
      phone_number: '+1112223333',
    }),
  }).then(r => r.json());

  console.log(updated.first_name);
  console.log(updated.last_name);
  console.log(updated.phone_number);
}

main();
04

Полная замена через PUT

#

Прочитайте текущий профиль, затем отправьте PUT со всеми полями, но измените `email`. Выведите обновлённый email для подтверждения.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // PUT требует все поля — сначала прочитайте!
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const { token } = await fetch(`${BASE_URL}/api/auth/token/`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' }),
  }).then(r => r.json());

  const headers = {
    'Authorization': `Token ${token}`,
    'Content-Type': 'application/json',
  };
  const PROFILE_URL = `${BASE_URL}/api/users/profile/`;

  const current = await fetch(PROFILE_URL, { headers }).then(r => r.json());

  const updated = await fetch(PROFILE_URL, {
    method: 'PUT', headers,
    body: JSON.stringify({
      username: current.username,
      email: '[email protected]',
      first_name: current.first_name || '',
      last_name: current.last_name || '',
      phone_number: current.phone_number || '',
    }),
  }).then(r => r.json());

  console.log(updated.email);
}

main();
05

Функция updateProfile()

#

Напишите async-функцию `updateProfile(headers, fields)`, которая PATCHит профиль и возвращает результат. Вызовите её дважды с разными полями.

const BASE_URL = 'https://apilearn.tukas.dev';

async function updateProfile(headers, fields) {
  // PATCH /api/users/profile/ с fields, вернуть результат
}

async function main() {
  const { token } = await fetch(`${BASE_URL}/api/auth/token/`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' }),
  }).then(r => r.json());

  const headers = {
    'Authorization': `Token ${token}`,
    'Content-Type': 'application/json',
  };

  // вызвать updateProfile дважды с разными полями
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function updateProfile(headers, fields) {
  return fetch(`${BASE_URL}/api/users/profile/`, {
    method: 'PATCH',
    headers,
    body: JSON.stringify(fields),
  }).then(r => r.json());
}

async function main() {
  const { token } = await fetch(`${BASE_URL}/api/auth/token/`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' }),
  }).then(r => r.json());

  const headers = {
    'Authorization': `Token ${token}`,
    'Content-Type': 'application/json',
  };

  const r1 = await updateProfile(headers, { first_name: 'Test' });
  console.log(r1.first_name);

  const r2 = await updateProfile(headers, { phone_number: '+9998887777' });
  console.log(r2.phone_number);
}

main();