курсач / 1302_3_Курсовая
.pdf21
Вывод:
На малых объемах (1000 записей) SOAP проигрывает в 2 раза, вероятно, из-за накладных расходов на установление соединения и более тяжелых заголовков.
На больших объемах (20 000 записей) разрыв составляет внушительные 18 секунд (30 сек против 48 сек). Это объясняется кумулятивным эффектом:
1.Лишние 300 КБ данных требуют дополнительного времени на передачу.
2.Тяжелый парсинг XML (150 мс) добавляется к общему времени.
3.Большее количество TCP-пакетов увеличивает вероятность задержек.
3.3. Итоговое сравнение и выводы
Проведенное исследование позволяет сформировать сводную сравнительную характеристику реализованных сервисов.
1.Экономия трафика: REST выигрывает с преимуществом в 15%.
2.Скорость клиента (CPU): REST демонстрирует подавляющее преимущество, работая в 30 раз быстрее. Это делает его безальтернативным выбором для мобильных веб-приложений, где заряд батареи и мощность процессора ограничены.
3.Скорость сети: В условиях плохого интернета REST позволяет получить данные значительно быстрее (на 30-50%). Пользователь SOAP-сервиса на 20 000 записях вынужден ждать почти минуту (48 с), тогда как пользователь REST – полминуты (30 с).
Таким образом, гипотеза о тяжеловесности SOAP подтвердилась практическими экспериментами. Использование XML создает двойную нагрузку: на канал связи (избыточные теги) и на процессор клиента (сложный парсинг DOM).
Характеристики ЭВМ, на которой производился тест:
•ОС: Windows 10
•Процессор: AMD Ryzen 5 4500U
•Оперативная память: 32 гб
•Среда выполнения: Node.js v20.19.1, Google Chrome v143.
22
ВЫВОДЫ
В ходе выполнения курсовой работы были реализованы и исследованы два типа веб-сервисов: SOAP и REST.
Практическая реализация показала, что:
1.Сложность разработки: REST значительно проще в реализации и отладке. Для SOAP требуется написание WSDL-схем и ручное формирование XML-структур (при отсутствии кодогенерации), что усложняет разработку клиентской части в браузере.
2.Производительность: REST (JSON) демонстрирует подавляющее преимущество перед SOAP (XML) в скорости обработки данных на клиенте (до 40 раз быстрее) и эффективности использования сети.
3.Область применения: SOAP остается актуальным для систем, где критически важна строгая типизация и валидация данных на уровне протокола, однако для публичных веб-API и мобильных приложений использование REST является безальтернативным стандартом де-факто из-за экономии ресурсов устройства и трафика.
23
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
1.Fielding R.T. Architectural Styles and the Design of Network-based Software Architectures. – University of California, Irvine, 2000.
2.Simple Object Access Protocol (SOAP) 1.1 [Электронный ресурс] // W3C Note. – URL: https://www.w3.org/TR/2000/NOTE-SOAP-20000508/ (дата обращения: 19.12.2025).
3.Web Services Description Language (WSDL) 1.1 [Электронный ресурс] // W3C Note. – URL: https://www.w3.org/TR/wsdl (дата обращения: 19.12.2025).
4.RFC 7231. Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content [Электронный ресурс] // IETF. – URL: https://tools.ietf.org/html/rfc7231 (дата обращения: 19.12.2025).
5.ECMA-404. The JSON Data Interchange Syntax [Электронный ресурс] //
ECMA International. – URL: https://www.ecma-international.org/publications-and- standards/standards/ecma-404/ (дата обращения: 19.12.2025).
6.Richardson L., Ruby S. RESTful Web Services. – O'Reilly Media, 2007. – 448
с.
7.MDN Web Docs. Parsing XML with DOMParser [Электронный ресурс]. –
URL: https://developer.mozilla.org/en-US/docs/Web/API/DOMParser (дата |
обращения: |
||||
19.12.2025). |
|
|
|
|
|
8. |
Node.js |
Documentation. [Электронный |
ресурс]. |
– |
|
URL: https://nodejs.org/en/docs/ (дата обращения: 19.12.2025).
9.Vue.js Guide. The Progressive JavaScript Framework [Электронный ресурс].
–URL: https://vuejs.org/guide/introduction.html (дата обращения: 19.12.2025).
10.Erl T. Service-Oriented Architecture: Concepts, Technology, and Design. – Prentice Hall, 2005. – 792 с.
24
ПРИЛОЖЕНИЕ А
Код файла student.wsdl
<definitions name="StudentService" targetNamespace="http://www.examples.com/wsdl/StudentService.wsdl" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.examples.com/wsdl/StudentService.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<types>
<xsd:schema targetNamespace="http://www.examples.com/wsdl/StudentService.wsdl"> <!-- Тип Студент -->
<xsd:complexType name="Student"> <xsd:sequence>
<xsd:element name="id" type="xsd:int"/> <xsd:element name="name" type="xsd:string"/>
<xsd:element name="specialization" type="xsd:string"/> <xsd:element name="course" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
<!-- Get ONE -->
<xsd:element name="getStudentRequest"> <xsd:complexType>
<xsd:sequence>
<xsd:element name="id" type="xsd:int"/> </xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="getStudentResponse"> <xsd:complexType>
<xsd:sequence>
<xsd:element name="student" type="tns:Student"/> </xsd:sequence>
25
</xsd:complexType>
</xsd:element>
<!-- Get ALL -->
<xsd:element name="getStudentsRequest"> <xsd:complexType>
<xsd:sequence/> <!-- Пустой запрос --> </xsd:complexType>
</xsd:element>
<xsd:element name="getStudentsResponse"> <xsd:complexType>
<xsd:sequence>
<!-- Массив студентов -->
<xsd:element name="students" type="tns:Student" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<!-- Create -->
<xsd:element name="createStudentRequest"> <xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/> <xsd:element name="specialization" type="xsd:string"/> <xsd:element name="course" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="createStudentResponse"> <xsd:complexType>
<xsd:sequence>
<xsd:element name="student" type="tns:Student"/> </xsd:sequence>
</xsd:complexType>
26
</xsd:element>
</xsd:schema>
</types>
<!-- Messages -->
<message name="GetStudentInput"><part name="body" element="tns:getStudentRequest"/></message>
<message name="GetStudentOutput"><part name="body" element="tns:getStudentResponse"/></message>
<message name="GetStudentsInput"><part name="body" element="tns:getStudentsRequest"/></message>
<message name="GetStudentsOutput"><part name="body" element="tns:getStudentsResponse"/></message>
<message name="CreateStudentInput"><part name="body" element="tns:createStudentRequest"/></message>
<message name="CreateStudentOutput"><part name="body" element="tns:createStudentResponse"/></message>
<!-- PortType -->
<portType name="StudentPortType"> <operation name="getStudent">
<input message="tns:GetStudentInput"/> <output message="tns:GetStudentOutput"/>
</operation>
<operation name="getStudents">
<input message="tns:GetStudentsInput"/> <output message="tns:GetStudentsOutput"/>
</operation>
<operation name="createStudent">
<input message="tns:CreateStudentInput"/> <output message="tns:CreateStudentOutput"/>
</operation>
</portType>
<!-- Binding -->
27
<binding name="StudentBinding" type="tns:StudentPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="getStudent">
<soap:operation soapAction="getStudent"/> <input><soap:body use="literal"/></input> <output><soap:body use="literal"/></output>
</operation>
<operation name="getStudents"> <soap:operation soapAction="getStudents"/> <input><soap:body use="literal"/></input> <output><soap:body use="literal"/></output>
</operation>
<operation name="createStudent"> <soap:operation soapAction="createStudent"/> <input><soap:body use="literal"/></input> <output><soap:body use="literal"/></output>
</operation>
</binding>
<service name="StudentService">
<port name="StudentPort" binding="tns:StudentBinding"> <soap:address location="http://localhost:8000/soap"/>
</port>
</service>
</definitions>
Листинг программного кода серверной части. index.ts import express from 'express';
import cors from 'cors'; import * as soap from 'soap'; import fs from 'fs';
import path from 'path';
import { restRouter } from '@/routes';
import { soapService } from '@/student/soap/student.soap'; import { initDb } from '@/database';
28
const app = express(); const PORT = 8000;
initDb();
app.use(cors());
app.use(express.json());
//1. REST API app.use('/api', restRouter);
//2. SOAP API
const wsdlPath = path.join(__dirname, 'student/soap/student.wsdl'); const wsdlXml = fs.readFileSync(wsdlPath, 'utf8');
app.listen(PORT, () => {
soap.listen(app, '/soap', soapService, wsdlXml, () => { console.log(`Server running on port ${PORT}`);
console.log(`REST Endpoint: http://localhost:${PORT}/api/students`); console.log(`SOAP WSDL: http://localhost:${PORT}/soap?wsdl`);
});
});
Листинг программного кода серверной части. student.repository.ts import { db } from '@/database';
import { Student } from './entity/student.entity';
class StudentRepository {
async countAll(): Promise<number> { return new Promise((resolve, reject) => {
db.get('SELECT COUNT(*) as count FROM students', (err, row: any) => { if (err) reject(err);
else resolve(row.count); });
29
});
}
async findAll(): Promise<Student[]> { return new Promise((resolve, reject) => {
const sql = 'SELECT * FROM students'; db.all(sql, [], (err, rows) => {
if (err) reject(err);
else resolve(rows as Student[]); });
});
}
async findById(id: number): Promise<Student | undefined> { return new Promise((resolve, reject) => {
const sql = 'SELECT * FROM students WHERE id = ?'; db.get(sql, [id], (err, row) => {
if (err) reject(err);
else resolve(row as Student); });
});
}
async create(data: Omit<Student, 'id'>): Promise<Student> { return new Promise((resolve, reject) => {
const sql = 'INSERT INTO students (name, specialization, course) VALUES (?, ?, ?)'; db.run(sql, [data.name, data.specialization, data.course], function (err) {
if (err) reject(err);
else resolve({ id: this.lastID, ...data } as Student); });
});
}
async delete(id: number): Promise<boolean> { return new Promise((resolve, reject) => {
30
const sql = 'DELETE FROM students WHERE id = ?'; db.run(sql, [id], function (err) {
if (err) reject(err);
else resolve(this.changes > 0); });
});
}
async clearAll(): Promise<void> {
return new Promise((resolve, reject) => { db.run('DELETE FROM students', (err) => {
if (err) reject(err); else resolve();
});
});
}
async seed(count: number): Promise<void> { return new Promise((resolve, reject) => {
const specializations = ['IT', 'DevOps', 'QA', 'Design', 'Manager', 'Analyst'];
db.serialize(() => {
db.run('BEGIN TRANSACTION');
const stmt = db.prepare(
'INSERT INTO students (name, specialization, course) VALUES (?, ?, ?)' );
for (let i = 0; i < count; i++) {
const name = `Student ${Math.floor(Math.random() * 10000)}`;
const spec = specializations[Math.floor(Math.random() * specializations.length)]; const course = Math.floor(Math.random() * 5) + 1;
stmt.run(name, spec, course);
}
