920 likes | 936 Views
Explore the concepts and principles of RESTful web services in Java, including key concepts like client-server interaction, HTTP commands, and canonical HTTP method usage. Learn about Representational State Transfer architecture and the fundamentals of creating REST APIs.
E N D
2012-2016 RESTful веб-служби (Java)
Веб-служби. SOAP 1.1 Web Services REST (Java)
SOAP 1.1. Форматизапиту(request) та відповіді(response) Web Services REST (Java)
HTTP POST. Форматизапиту(request) та відповіді(response) Web Services REST (Java)
Web Services REST (Java) REST веб-служби. Ідеологія архітектурного стилю • Абревіатура REST означає Representational State Transfer (репрезентативна передача стану). Цим підкреслюється, що REST- веб-служби спираються на спеціальний архітектурний стиль. Відповідний архітектурний стиль і сам термін REST у 2000 році увів Рой Томас Філдінг (Roy Thomas Fielding), відомий роботою над специфікацією Інтернет-протоколу HTTP. • REST спирається на взаємодію “клієнт-сервер” з орієнтацією на традиційні базові принципи Інтернету: • клієнт взаємодіє із ресурсами, при тому ресурсом може бути будь-що, що можна поіменувати та репрезентувати (подати) із використанням різноманітних Інтернет-засобів; • для звернень використовується виключно стандартні HTTP-команди, найчастіше POST, GET, PUT, DELETE. “Архітектурний стиль з орієнтацією на дані” Наявна підтримка базо-вих функцій над даними “C R U D”
REST веб-служби. Ключові концепції (1/6) У Web-сервісах REST ключовими вважаються наступні концепції : • “клієнт-серверна” взаємодія; • клієнт взаємодіє із ресурсами, при тому ресурсом може бути будь-що, що можна поіменувати та репрезентувати (подати) із використанням різноманітних Інтернет-засобів; • для звернень використовується виключно стандартні HTTP-команди, найчастіше POST, GET, PUT, DELETE. Більш того, варто уточнити, що REST API ґрунтується на “канонічному” використанні HTTP-команд; Зауважимо, що у перших трьох з них по суті повторю-ються основні ідеологічні положення стилю REST Web Services REST (Java) 6
REST веб-служби. Ключові концепції. (2/6) “Канонічне” використання HTTP-методів Термін “канонічне” означає, що при роботі з ресурсами використання HTTP-команд узгоджується з робочою пропозицією Request for Comments (RFC) 2616, а саме: • для створення ресурсу використовується виключно команда POST; // Create • для отримання ресурсу — виключно команда GET; // Read • для оновлення (заміни) ресурсу — команда PUT; // Update • для видалення ресурсу — DELETE. // Delete Взагалі кажучи, у Web API четвірка наведених команд може використовуватись не тільки вказаним чином, тобто не тільки канонічно. Наприклад, командою GET можуть, запускатись віддалені методи на зразок: GET /addcontact?name=Homa&addr=Hotiv. У подібних випадках кажуть про використання HTTP-команд не в REST-стилі (не RESTfully використання). “C R U D” Web Services REST (Java) 7
REST веб-служби. Ключові концепції (3/6) (продовження переліку) У Web-сервісах REST ключовими вважаються наступні концепції (продовження переліку) : • відсутнє збереження станів “клієнтів” (архітектурний принцип stateless); • використання для ідентифікації ресурсів URI такої структури, яка подібна до традиційної структури каталогів (або до структури namespaces); • форматами для передачі (репрезентації) даних у переважній більшості випадків виступають XML або JSON. Web Services REST (Java) 8
REST веб-служби. Ключові концепції (4/6) (продовження переліку) У Web-сервісах REST ключовими вважаються наступні концепції (продовження переліку) : • відсутнє збереження станів “клієнтів” (архітектурний принцип stateless); • використання для ідентифікації ресурсів URI такої структури, яка подібна до традиційної структури каталогів (або до структури namespaces); GET запити “рівня бази” та “рівня таблиці” http://localhost:8088/DBMS/rest/ws/base1 http://localhost:8088/DBMS/rest/ws/base1/table2 localhost:8088/DBMS/rest/ws/base1/table1/аttr1 Web Services REST (Java) 9
REST веб-служби. Ключові концепції (5/6) (продовження переліку) • У Web-сервісах REST ключовими вважаються наступні концепції (продовження переліку) : • форматами для передачі (репрезентації) даних у переважній більшості випадків виступають XML або JSON. http://localhost:8088/DBMS/rest/ws/base1/table2 json Web Services REST (Java) 10
REST веб-служби. Ключові концепції (6/6) http://localhost:8088/DBMS/rest/ws/base1 xml table2 table2 json table1 Web Services REST (Java)
Web Services REST (Java) Архітектурний стиль з орієнтацією на дані REST веб-служби. Огляд проектів URI=URL+URN Структуровані / “ієрархічні” дані XML, Json Проект Contacts Ресурсом може бути будь-що, що можна поіменувати (URI — Uniform Resource Identifier) та репрезентувати . ПроектGreeting... (кілька ресурсних класів) “Ієрархічні” імена (URN) Дані Проект DBMS Проект Contacts Контакти Рахунки Школа Унів-т Спорт Хоббі Родичі Банки Комунальні Приклади URI Теніс Бадм-н Бридж Http GET http://… /Контакти/Спорт/Теніс/Віталій http://localhost:8088/Contacts/rest_serv/cont/Homa
Web Services REST (Java) REST веб-служби. Приклад запиту Http GET Http Get http://localhost:8088/Contacts/rest_serv/cont/Homa Http Get запит
Web Services REST (Java) URI. ПрикладиHTTP Get запитів Http Get запит • Кожен ресурс ідентифікується з використанням URI. Http Get запит
Web Services REST (Java) URI. ПрикладHTTP Post запиту. Postman http://localhost:8088/Contacts/rest_serv/cont/?name=Petro&addr=Podil 1) Http Post запит • Кожен ресурс ідентифікується з використанням URI. Postman 2) тепер є можливість здійснити Http Get запит із Petro
1) Http Post запит Повторний Post Postman .../cont/?name=Petro&addr=Podil 2) Http Post (повторний запит з тими ж параметрами) Web Services REST (Java)
Web Services REST (Java) REST веб-служби. Приклади репрезентацій (1/2) Клієнт взаємодіє із ресурсами, при тому ресурсом може бути будь-що, що можна поіменувати та репрезентувати (подати) із використанням різноманітних Інтернет-засобів Приклади з проектуGreeting2015 Http Get запит Http Get запит text json Http Get запит xml
Web Services REST (Java) REST веб-служби. Приклади репрезентацій (2/2) Клієнт взаємодіє із ресурсами, при тому ресурсом може бути будь-що, що можна поіменувати та репрезентувати (подати) із використанням різноманітних Інтернет-засобів Http Get запит Приклади з проектуContacts json Http Get запит xml
Web Services REST (Java) Служби REST. Основні положення • Будь-що в REST розглядається як ресурс. • Кожен ресурс ідентифікується із використанням URI. • Застовуються для роботи із сервісом виключно HTTP-операціїPOST, GET, PUT, DELETE, забезпечуючи CRUD (Create, Read, Update, Delete) – створення, читання, оновлення та видалення ресурсів-даних. • Стиль – безстановий (stateless). (Кожен запит є “ізольованим”, тобто він має містити всю інформацію, необхідну для роботи з потрібним ресурсом.) • Взаємодія зі службою REST провадиться із використанням MIME-репрезентацій, зокрема XML, JSON. (MIME – Multipurpose Internet Mail Extensions).
Java Community Process (JCP). Java Specification Request (JSR) JSR 311:JAX-RS: The JavaTM API for RESTful Web Services Web Services REST (Java)
Проект Contacts Web Services REST (Java)
Проект Contacts (Eclipse Java EE IDE for Web Developers. Version: Mars Release 4.5.0) Web Services REST (Java)
Проект Contacts. Ще деякі особливості Web Services REST (Java)
Клас «ресурсів» class ContactResource (1/3) http://localhost:8088/Contacts/rest_serv/cont/Petro package cyb.ttp.rs; import javax.ws.rs.Consumes; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Response; @Path("/cont") publicclass ContactResource { @Produces({"application/xml", "application/json"}) @Path("{name}") @GET public Contact getContact(@PathParam("name") String name) { Contact contact = ContactService.getContact(name); if (contact == null) { returnnew Contact("Name not found", "------"); } returncontact; } Http Get запит .../cont/Petro Варіанти! Web Services REST (Java) Продовження опису див. на наст.слайді
Клас «ресурсів» class ContactResource (2/3)(продовження опису, метод addContact) Продовження опису класу ContactResource @POST @Consumes("application/x-www-form-urlencoded") public Response addContact(@FormParam("name") String name, @FormParam("addr") String addr) { if (ContactService.getContact(name) != null) return Response.status(Response.Status.BAD_REQUEST). entity("Contact " + name + " already exists").type("text/plain").build(); ContactService.addContact(new Contact(name, addr)); return Response.ok().build(); } } .../cont/?name=Petro&addr=Podil Http Post запит Postman Web Services REST (Java)
Клас «ресурсів» class ContactResource (3/3) (анотація @Produces ) . . . publicclass ContactResource { @Produces({"application/xml", "application/json"}) @Path("{name}") @GET public Contact getContact(@PathParam("name") String name) { ... } Варіанти! Web Services REST (Java)
Клас Contact package cyb.ttp.rs; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement publicclass Contact { private String name; private String addr; public Contact(String name, String addr){ this.name = name; this.addr = addr; } public Contact(){ } public String getName() { returnname; } ... // інші get- , set- } Порядок? Див. наступний проект Greeting2015 Web Services REST (Java)
Допоміжний (Helper) класContactService package cyb.ttp.rs; import java.util.HashMap; import java.util.Map; publicclass ContactService { publicstaticvoid addContact(Contact contact) { contacts.put(contact.getName(), contact); } publicstaticvoid removeContact(String name) { contacts.remove(name); } publicstatic Contact getContact(String name) { returncontacts.get(name); } privatestatic Map<String, Contact> contacts = new HashMap<String, Contact>(); static { createContacts(); } privatestaticvoid createContacts() { addContact(new Contact("Homa", "Hotiv")); addContact(new Contact("Savva", "Sovky")); } } Web Services REST (Java)
Клас ContactApplication package cyb.ttp.rs; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("rest_serv") publicclass ContactApplication extends Application { } Немає потреби у використанні конфігураційного файла web.xml http://localhost:8088/Contacts/rest_serv/cont/Petro Ім’я проекту Web Services REST (Java)
Проект DBMS Web Services REST (Java)
Бізнес-логіка. Діаграма класів Не реалізовано! Web Services REST (Java)
Приклад Http GET запиту (“рівня бази”). База base2 (xml-репрезентація) http://localhost:8088/DBMS/rest/ws/base2 xml Web Services REST (Java)
База base1(xml-репрезентація) http://localhost:8088/DBMS/rest/ws/base1 Ще один Http GET запит “рівня бази”(у Google Chrome) table2 xml table1 Web Services REST (Java)
Http GET запит “рівня таблиці”. Таблиця table1 з бази base1 (json-репрезентація) http://localhost:8088/DBMS/rest/ws/base1/table2 json Фрагмент з попереднього слайду з xml-кодом таблиці table2 http://localhost:8088/DBMS/rest/ws/base1 xml table2 Web Services REST (Java)
Приклад запиту HTTP DELETE HTTP DELETE (Postman) 1 http://localhost:8088/DBMS/rest/ws/base1/table2 2 HTTP GET (Google Chrome) http://localhost:8088/DBMS/rest/ws/base1 HTTP GET запит після виконання HTTP DELETE (таблиця table2відсутня) 3 HTTP GET (Google Chrome) localhost:8088/DBMS/rest/ws/base1/table2 Web Services REST (Java)
Проект DBMS http://localhost:8088/DBMS/rest/ws/base1 xml table2 http://localhost:8088/DBMS/rest/ws/base1/table2 table1 table2 json Web Services REST (Java)
package cyb.ttp; import java.util.HashMap; import java.util.Map; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlRootElement @XmlType(propOrder ={"name", "tables"}) publicclass Base { private String name; private Map<String, Table> tables = new HashMap<String, Table>(); public Base(String name, Map<String,Table> tables){ this.name = name; this.tables = tables; } . . . } Класи Base, Table, Attr propOrder - тут не важливо package cyb.ttp; import java.util.List; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlRootElement @XmlType(propOrder ={"name", "data", "attrs"}) publicclass Table { private String name; private String data; private List<Attr> attrs; public Table(String name, String data, List<Attr> attrs) { this.name = name; this.data = data; this.attrs = attrs; } . . . } propOrder! package cyb.ttp; publicclass Attr { private String nameAttr; private String typeAttr; public Attr(String nameAttr, String typeAttr) { this.nameAttr = nameAttr; this.typeAttr = typeAttr; } . . . } Web Services REST (Java)
Анотація @XmlType(propOrder ={"name", "tables"}) @XmlRootElement @XmlType(propOrder ={"name", "tables"}) publicclass Base { private String name; private Map<String, Table> tables = new HashMap<String, Table>(); . . . } propOrder - тут не важливо @XmlRootElement @XmlType(propOrder ={"name", "data", "attrs"}) publicclass Table { private String name; private String data; private List<Attr> attrs; . . . } propOrder! package cyb.ttp; publicclass Attr { private String nameAttr; private String typeAttr; . . . } Web Services REST (Java)
Анотація @XmlRootElement Важливо для xml-репрезентацій @XmlRootElement @XmlType(propOrder ={"name", "data", "attrs"}) publicclass Table { private String name; private String data; private List<Attr> attrs; . . . } localhost:8088/DBMS/rest/ws/base1/table2 Web Services REST (Java) json
package cyb.ttp; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; publicclass DBService { privatestatic Map<String, Base> bases = new HashMap<String, Base>(); publicstaticvoid addDB(Base base) { bases.put(base.getName(), base); } publicstaticvoid removeDB(String name) { bases.remove(name); } publicstatic Base getDB(String name) { returnbases.get(name); } publicstaticvoid addTable(String nameDB, Table table) { Base db = getDB(nameDB); db.getTables().put(table.getName(), table); } publicstaticvoid removeTable(String nameDB, String nameT) { Base db = getDB(nameDB); db.getTables().remove(nameT); } publicstatic Table getTable(String nameDB, String nameT) { Base db = getDB(nameDB); returndb.getTables().get(nameT); } static { createBases(); } Клас DBService (1/2) Web Services REST (Java)
privatestaticvoid createBases() { Attr attr1 = new Attr("at1", "type1"); Attr attr2 = new Attr("at2", "type2"); Attr attr3 = new Attr("at3", "type3"); List<Attr> shema1 = new ArrayList<Attr>(); List<Attr> shema2 = new ArrayList<Attr>(); List<Attr> shema3 = new ArrayList<Attr>(); shema1.add(attr1); shema1.add(attr2); shema2.add(attr1); shema2.add(attr3); shema3.add(attr3); Table tbl1 = new Table("table1", "Table-1-(data)",shema1); Table tbl2 = new Table("table2", "Table-2-(data)",shema2); Table tbl3 = new Table("table3", "Table-3-(data)",shema3); Map<String, Table> db1Tables = new HashMap<String, Table>(); Map<String, Table> db2Tables = new HashMap<String, Table>(); db1Tables.put("table1", tbl1); db1Tables.put("table2", tbl2); db2Tables.put("table3", tbl3); Base db1 = new Base("base1", db1Tables); Base db2 = new Base("base2", db2Tables); addDB(db1); addDB(db2); } } Клас DBService (2/2) base1 base2 Web Services REST (Java)
Клас DBMSApplication localhost:8088/DBMS/rest/ws/base2 package cyb.ttp; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("rest") publicclass DBMSApplication extends Application { } Web Services REST (Java)
localhost:8088/DBMS/rest/ws/base2 package cyb.ttp; import java.util.ArrayList; import java.util.HashMap; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @Path("/ws") publicclass DBMSResource { @Produces({"application/xml"}) @Path("{nameDB}") @GET public Base getDB(@PathParam("nameDB") String name) { Base db = DBService.getDB(name); if (db == null) { returnnew Base("Name not found", new HashMap<String, Table>()); } returndb; } @Path("{nameDB}") @DELETE publicvoid deleteDB(@PathParam("nameDB") String name) { DBService.removeDB(name); //спрощений варіант } Ресурсний клас DBMSResource (поч.) xml Web Services REST (Java)
localhost:8088/DBMS/rest/ws/base1/table1 Ресурсний клас DBMSResource (заверш.) json @Produces({"application/json"}) @Path("{nameDB}/{nameTable}") @GET public Table getTable(@PathParam("nameDB") String nameDB, @PathParam("nameTable") String nameTable ) { Table t = DBService.getTable(nameDB,nameTable); if (t == null) { returnnew Table("Name not found", "----", new ArrayList<Attr>()); } returnt; } @Path("{nameDB}/{nameTable}") @DELETE publicvoid deleteTable(@PathParam("nameDB") String nameDB, @PathParam("nameTable") String nameTable) { DBService.removeTable(nameDB, nameTable); //спрощений варіант } } Web Services REST (Java)
Ресурсний клас DBMSResource. Можливості використання ще одного “рівня даних” localhost:8088/DBMS/rest/ws/base1/table1/аttr1 @Produces({"application/json"}) @Path("{nameDB}/{nameTable}/{nameAttr}") @GET public Attr getAttr(@PathParam("nameDB") String nameDB, @PathParam("nameTable") String nameTable,@PathParam("nameAttr") String nameAttr) { . . . } @Path("{nameDB}/{nameTable}/{nameAttr}") @DELETE publicvoid deleteAttr(@PathParam("nameDB") String nameDB, @PathParam("nameTable") String nameTable,@PathParam("nameAttr") String nameAttr) { . . . } } Web Services REST (Java)
Клас DBMSResource. Реалізація Delete-методів . . . @Path("{nameDB}") @DELETE publicvoid deleteDB(@PathParam("nameDB") String name) { DBService.removeDB(name); //спрощений варіант } . . . . . . @Path("{nameDB}") @DELETE public Response deleteDB(@PathParam("nameDB") String name) { if (DBService.getDB(name)== null) return Response.status(Response.Status.BAD_REQUEST). entity("DB '" + name + "' not found").type("text/plain").build(); DBService.removeDB(name); return Response.ok().build(); // } . . . Web Services REST (Java)
Таблиці. Використання HTTP DELETE, HTTP GET HTTP DELETE (Postman) 1 http://localhost:8088/DBMS/rest/ws/base1/table2 @Path("{nameDB}/{nameTable}") @GET public Table getTable( ... } @Path("{nameDB}/{nameTable}") @DELETE publicvoid deleteTable( ... } } 2 HTTP GET (Google Chrome) localhost:8088/DBMS/rest/ws/base1/table2 Web Services REST (Java)
Бази. Використання HTTP DELETE 1) HTTP DELETE localhost:8088/DBMS/rest/ws/base1 2) HTTP DELETE(повторний) localhost:8088/DBMS/rest/ws/base1 Web Services REST (Java)
Приклади використання HTTP DELETE, HTTP GET HTTP DELETE (Postman) 1 http://localhost:8088/DBMS/rest/ws/base1/table2 Вилучаємо table2 2 HTTP GET (Google Chrome) http://localhost:8088/DBMS/rest/ws/base1 Отримуємоbase1 (таблиця table2відсутня) 3 HTTP GET (Google Chrome) localhost:8088/DBMS/rest/ws/base1/table2 Web Services REST (Java) Намагаємось отриматитаблицю table2
Ще один приклад проекту(проектGreeting2015) Web Services REST (Java)