API и HTTP-клиенты

Фреймворк Marko предоставляет мощные возможности для работы с внешними сервисами и API. Для взаимодействия с внешними источниками данных, такими как REST API или GraphQL, часто используется HTTP-клиент. Marko сам по себе не включает в себя встроенные средства для работы с HTTP-запросами, однако легко интегрируется с внешними библиотеками, такими как axios, fetch, и другие.

Работа с API в Marko

Для начала необходимо правильно настроить HTTP-клиент. Рассмотрим использование популярной библиотеки axios для отправки HTTP-запросов.

Установка axios

Чтобы начать использовать axios, нужно установить его в проект:

npm install axios

После установки можно подключить библиотеку в компонент Marko.

Пример использования axios в компоненте Marko

// файл MyComponent.marko
import axios from 'axios';

export default class {
  async onCreate() {
    try {
      const response = await axios.get('https://api.example.com/data');
      this.data = response.data;
    } catch (error) {
      this.error = error;
    }
  }

  onInput(input) {
    // Можно использовать входные данные, если необходимо
  }
}

В этом примере, при создании компонента, выполняется HTTP-запрос для получения данных с удаленного API. В случае успешного ответа, данные сохраняются в свойстве компонента this.data, а в случае ошибки — в this.error.

Обработка асинхронных запросов

При работе с внешними API часто возникает необходимость в асинхронных операциях, таких как ожидание ответа сервера. В Marko можно использовать async/await для работы с асинхронными запросами.

Пример компонента, который загружает данные из API и отображает их на странице:

// файл DataLoader.marko
import axios from 'axios';

export default class {
  async onCreate() {
    this.loading = true;
    try {
      const response = await axios.get('https://api.example.com/items');
      this.items = response.data;
    } catch (error) {
      this.error = 'Ошибка загрузки данных';
    } finally {
      this.loading = false;
    }
  }
}

В этом примере при создании компонента отправляется асинхронный запрос, и в процессе ожидания отображается индикатор загрузки. После завершения запроса данные сохраняются в свойство компонента this.items, либо выводится ошибка.

Использование fetch вместо axios

Кроме axios, можно использовать встроенный в браузер fetch для выполнения HTTP-запросов. Преимущество fetch заключается в том, что это стандартная Web API, не требующая установки дополнительных пакетов.

Пример использования fetch:

// файл MyComponent.marko
export default class {
  async onCreate() {
    this.loading = true;
    try {
      const response = await fetch('https://api.example.com/data');
      if (!response.ok) {
        throw new Error('Ошибка запроса');
      }
      this.data = await response.json();
    } catch (error) {
      this.error = error.message;
    } finally {
      this.loading = false;
    }
  }
}

В этом примере используется fetch для отправки GET-запроса. Важно помнить, что fetch не выбрасывает исключение в случае HTTP-ошибки (например, 404 или 500), поэтому нужно вручную проверять статус ответа и обрабатывать ошибки.

Обработка ошибок и исключений

Работа с внешними API часто связана с рисками возникновения ошибок, таких как отсутствие подключения к интернету, неверный формат данных, ошибки на сервере и другие. Важно грамотно обрабатывать эти ошибки, чтобы приложение оставалось стабильным и удобным для пользователя.

Для этого можно использовать конструкцию try/catch для отлова ошибок в асинхронных запросах, как показано в предыдущих примерах. Ошибки можно логировать, показывать пользователю понятные сообщения или предпринимать дополнительные действия в зависимости от ситуации.

Взаимодействие с API на стороне сервера

Хотя Marko изначально ориентирован на работу с клиентским кодом, его также можно использовать для серверных приложений, где есть необходимость в получении данных с удаленных API в процессе рендеринга.

Пример серверного компонента

На сервере можно использовать тот же подход с axios или fetch для получения данных. Например, в случае с серверным рендерингом можно выполнить запросы к API в методе onCreate компонента и передать данные в шаблон для рендеринга.

// файл ServerComponent.marko
import axios from 'axios';

export default class {
  async onCreate() {
    const response = await axios.get('https://api.example.com/items');
    this.items = response.data;
  }
}

В данном примере при рендеринге страницы на сервере выполняется запрос к API, и полученные данные передаются в шаблон для отображения. Такой подход позволяет загрузить все необходимые данные до того, как страница будет отправлена клиенту.

Параметры запросов

При работе с API часто возникает необходимость в передаче параметров, таких как параметры URL или данные в теле запроса. Эти параметры можно передавать через методы библиотеки HTTP-клиента, например, через params или data в axios.

Пример передачи параметров в GET-запросе

// файл ParamsExample.marko
import axios from 'axios';

export default class {
  async onCreate() {
    const response = await axios.get('https://api.example.com/items', {
      params: { category: 'books', page: 2 }
    });
    this.items = response.data;
  }
}

В этом примере параметры запроса передаются через объект params, который автоматически добавляет их к URL в виде строки запроса. Это удобно для фильтрации данных на сервере, например, для поиска или пагинации.

Пример передачи данных в POST-запросе

// файл PostExample.marko
import axios from 'axios';

export default class {
  async onCreate() {
    const response = await axios.post('https://api.example.com/items', {
      name: 'New Item',
      category: 'Books'
    });
    this.response = response.data;
  }
}

Здесь данные передаются в теле POST-запроса. Этот метод используется для отправки данных на сервер, например, для создания новых записей.

Заключение

Работа с API в Marko основана на использовании внешних HTTP-клиентов, таких как axios или fetch. При помощи этих инструментов можно легко отправлять запросы к внешним сервисам, обрабатывать ответы и интегрировать внешние данные в компоненты Marko. Важно помнить о правильной обработке ошибок, использовании асинхронных функций и передаче параметров в запросах.