Список пользователей

Javascript web service client

Используя Fetch API в JavaScript, можно реализовать полноценный клиент для Web API в стиле REST для взаимодействия с пользователем. Архитектура REST предполагает применение следующих методов или типов запросов HTTP для взаимодействия с сервером:

Рассмотрим, как создать свой клиент на javascript для API.

Создание сервера на node.js

Для начала определим сервер, который будет и будет собственно представлять Web API. В качестве примера возьмем Node.js. Для обработки запросов определим следующий файл server.js :

const http = require("http"); const fs = require("fs"); // данные, с которыми работает клиент const users = [ < id:1, name:"Tom", age:24>, < id:2, name:"Bob", age:27>, < id:3, name:"Alice", age:"23">] // обрабатываем полученные от клиента данные function getReqData(req) < return new Promise(async (resolve, reject) => < try < const buffers = []; for await (const chunk of req) < buffers.push(chunk); >const data = JSON.parse(Buffer.concat(buffers).toString()); resolve(data); > catch (error) < reject(error); >>); > http.createServer(async (request, response) => < // получение всех пользователей if (request.url === "/api/users" && request.method === "GET") < response.end(JSON.stringify(users)); >// получение одного пользователя по id else if (request.url.match(/\/api\/users\/(4+)/) && request.method === "GET") < // получаем id из адреса url const // получаем пользователя по id const user = users.find((u) =>u.id === parseInt(id)); // если пользователь найден, отправляем его if(user) response.end(JSON.stringify(user)); // если не найден, отправляем статусный код и сообщение об ошибке else< response.writeHead(404, < "Content-Type": "application/json" >); response.end(JSON.stringify(< message: "Пользователь не найден" >)); > > // удаление пользователя по id else if (request.url.match(/\/api\/users\/(4+)/) && request.method === "DELETE") < // получаем id из адреса url const // получаем индекс пользователя по id const userIndex = users.findIndex((u) =>u.id === parseInt(id)); // если пользователь найден, удаляем его из массива и отправляем клиенту if(userIndex > -1) < const user = users.splice(userIndex, 1)[0]; response.end(JSON.stringify(user)); >// если не найден, отправляем статусный код и сообщение об ошибке else< response.writeHead(404, < "Content-Type": "application/json" >); response.end(JSON.stringify(< message: "Пользователь не найден" >)); > > // добавление пользователя else if (request.url === "/api/users" && request.method === "POST") < try< // получаем данные пользователя const userData = await getReqData(request); // создаем нового пользователя const user = ; // находим максимальный id const u.id;>)) // увеличиваем его на единицу user.id = id + 1; // добавляем пользователя в массив users.push(user); response.end(JSON.stringify(user)); > catch(error)< response.writeHead(400, < "Content-Type": "application/json" >); response.end(JSON.stringify(< message: "Некорректный запрос" >)); > > // изменение пользователя else if (request.url === "/api/users" && request.method === "PUT") < try< const userData = await getReqData(request); // получаем пользователя по id const user = users.find((u) =>u.id === parseInt(userData.id)); // если пользователь найден, изменяем его данные и отправляем обратно клиенту if(user) < user.age = userData.age; user.name = userData.name; response.end(JSON.stringify(user)); >// если не найден, отправляем статусный код и сообщение об ошибке else< response.writeHead(404, < "Content-Type": "application/json" >); response.end(JSON.stringify(< message: "Пользователь не найден" >)); > > catch(error)< response.writeHead(400, < "Content-Type": "application/json" >); response.end(JSON.stringify(< message: "Некорректный запрос" >)); > > else if (request.url === "/" || request.url === "/index.html") < fs.readFile("index.html", (error, data) =>response.end(data)); > else< response.writeHead(404, < "Content-Type": "application/json" >); response.end(JSON.stringify(< message: "Ресурс не найден" >)); > >).listen(3000, ()=>console.log("Сервер запущен по адресу http://localhost:3000"));

Разберем в общих чертах этот код. Вначале идет определение данных, с которыми будет работать клиент:

Читайте также:  Слайдер и размер текста

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

Далее определена функция getReqData() , которая извлекает из запроса присланные от клиента данные и конвертирует их в формат json (предполагается, что клиент будет присылать данные в формате json):

function getReqData(req) < return new Promise(async (resolve, reject) => < try < const buffers = []; for await (const chunk of req) < buffers.push(chunk); >const data = JSON.parse(Buffer.concat(buffers).toString()); resolve(data); > catch (error) < reject(error); >>); >

Причем результат функции определен в виде промиса. Если данные успешно распарсены, то передаем через промис распарсенный объект. Если же произошла ошибка, то передаем сообщение об ошибке.

Далее для каждого типа запросов определен определенный сценарий.

Когда приложение получает запрос типа GET по адресу «api/users», то срабатывает следующий код:

if (request.url === «/api/users» && request.method === «GET»)

Здесь просто отправляем выше определенный массив users.

Когда клиент обращается к приложению для получения одного объекта по id в запрос типа GET по адресу «api/users/», то срабатывает следующий код:

else if (request.url.match(/\/api\/users\/(3+)/) && request.method === "GET") < // получаем id из адреса url const получаем пользователя по id const user = users.find((u) =>u.id === parseInt(id)); // если пользователь найден, отправляем его if(user) response.end(JSON.stringify(user)); // если не найден, отправляем статусный код и сообщение об ошибке else< response.writeHead(404, < "Content-Type": "application/json" >); response.end(JSON.stringify(< message: "Пользователь не найден" >)); > >

В этом случае нам надо найти нужного пользователя по id в массиве, а если он не был найден, возвратить статусный код 404 с некоторым сообщением в формате JSON.

При получении DELETE-запроса по адресу «/api/users/:id» находим индекс объекта в массива. И если объект найден, то удаляем его из массива и отправляем клиенту:

// удаление пользователя по id else if (request.url.match(/\/api\/users\/(9+)/) && request.method === "DELETE") < // получаем id из адреса url const получаем индекс пользователя по id const userIndex = users.findIndex((u) =>u.id === parseInt(id)); // если пользователь найден, удаляем его из массива и отправляем клиенту if(userIndex > -1) < const user = users.splice(userIndex, 1)[0]; response.end(JSON.stringify(user)); >// если не найден, отправляем статусный код и сообщение об ошибке else< response.writeHead(404, < "Content-Type": "application/json" >); response.end(JSON.stringify(< message: "Пользователь не найден" >)); > >

Если объект не найден, возвращаем статусный код 404.

При получении запроса с методом POST по адресу «/api/users» используем функцию getReqData() для извлечения данных из запроса:

else if (request.url === "/api/users" && request.method === "POST") < try< // получаем данные пользователя const userData = await getReqData(request); // создаем нового пользователя const user = ; // находим максимальный id const u.id;>)) // увеличиваем его на единицу user.id = id + 1; // добавляем пользователя в массив users.push(user); response.end(JSON.stringify(user)); > catch(error)< response.writeHead(400, < "Content-Type": "application/json" >); response.end(JSON.stringify(< message: "Некорректный запрос" >)); > >

Поскольку при выполнении функции промис может передавать ошибку (например, в результате парсинга в JSON), оборачиваем весь код в try..catch . После получения данных нам надо создать новый объект и добавить его в массив объектов.

Если приложению приходит PUT-запрос, то также с помощью функции getReqData() получаем отправленные клиентом данные. Если объект найден в массиве, то изменяем его, иначе отправляем статусный код 404:

// изменение пользователя else if (request.url === "/api/users" && request.method === "PUT") < try< const userData = await getReqData(request); // получаем пользователя по id const user = users.find((u) =>u.id === parseInt(userData.id)); // если пользователь найден, изменяем его данные и отправляем обратно клиенту if(user) < user.age = userData.age; user.name = userData.name; response.end(JSON.stringify(user)); >// если не найден, отправляем статусный код и сообщение об ошибке else< response.writeHead(404, < "Content-Type": "application/json" >); response.end(JSON.stringify(< message: "Пользователь не найден" >)); > > catch(error)< response.writeHead(400, < "Content-Type": "application/json" >); response.end(JSON.stringify(< message: "Некорректный запрос" >)); > >

Таким образом, мы определили простейший API. Теперь добавим код клиента.

Определение клиента

При обращении к корню веб-приложению или по адресу «/index.html», сервер будет отдавать файл index.html. Поэтому в одной папке с файлом сервера определим файл index.html со следующим кодом:

       

Список пользователей

Сбросить
IdИмявозраст

Основная логика здесь заключена в коде javascript. При загрузке страницы в браузере получаем все объекты из БД с помощью функции getUsers:

async function getUsers() < // отправляет запрос и получаем ответ const response = await fetch("/api/users", < method: "GET", headers: < "Accept": "application/json" >>); // если запрос прошел нормально if (response.ok === true) < // получаем данные const users = await response.json(); let rows = document.querySelector("tbody"); users.forEach(user =>< // добавляем полученные элементы в таблицу rows.append(row(user)); >); > >

Для добавления строк в таблицу используется функция row() , которая возвращает строку. В этой строке будут определены ссылки для изменения и удаления пользователя.

Ссылка для изменения пользователя с помощью функции getUser() получает с сервера выделенного пользователя:

async function getUser(id) < const response = await fetch("/api/users/" + id, < method: "GET", headers: < "Accept": "application/json" >>); if (response.ok === true) < const user = await response.json(); const form = document.forms["userForm"]; form.elements["id"].value = user.id; form.elements["name"].value = user.name; form.elements["age"].value = user.age; >>

И выделенный пользователь добавляется в форму над таблицей. Эта же форма применяется и для добавления объекта. С помощью скрытого поля, которое хранит id пользователя, мы можем узнать, какое действие выполняется — добавление или редактирование. Если id равен 0, то выполняется функция createUser, которая отправляет данные в POST-запросе:

async function createUser(userName, userAge) < const response = await fetch("api/users", < method: "POST", headers: < "Accept": "application/json", "Content-Type": "application/json" >, body: JSON.stringify(< name: userName, age: parseInt(userAge, 10) >) >); if (response.ok === true) < const user = await response.json(); reset(); document.querySelector("tbody").append(row(user)); >>

Если же ранее пользователь был загружен на форму, и в скрытом поле сохранился его id, то выполняется функция editUser, которая отправляет PUT-запрос:

async function editUser(userId, userName, userAge) < const response = await fetch("api/users", < method: "PUT", headers: < "Accept": "application/json", "Content-Type": "application/json" >, body: JSON.stringify(< id: userId, name: userName, age: parseInt(userAge, 10) >) >); if (response.ok === true) < const user = await response.json(); reset(); document.querySelector("tr[data-rowid='" + user.id + "']").replaceWith(row(user)); >>

В конце запустим файл сервера server.js командой:

Источник

Оцените статью