Бул REST талдоосунун акыркы бөлүгү. Мурунку бөлүктөрдө:
Долбоорду түзүү
Бул бөлүмдө биз Spring Boot аркылуу кичинекей RESTful тиркемесин түзөбүз. Биздин колдонмо анализдин акыркы бөлүгүндөгү мисалдан кардарларга CRUD (Түзүү, окуу, жаңыртуу, жок кылуу) операцияларын ишке ашырат . Биринчиден, File -> New -> Project менюсу аркылуу жаңы Spring Boot тиркемесин түзөлү ... Ачылган терезеден Spring Initializr тандаңыз жана Project SDK дегенди белгилеңиз: Кийинки баскычын басыңыз. Кийинки терезеде, Maven долбоорунун түрүн көрсөтүңүз, Топту жана Артефактты белгилеңиз: Кийинки баскычын чыкылдатыңыз. Кийинки терезеде биз долбоорго керектүү Spring Framework компоненттерин тандап алышыбыз керек. Жазгы Желе биз үчүн жетиштүү болот: Кийинки баскычын чыкылдатыңыз. Андан кийин, долбоордун атын жана файл тутумунда жайгашкан жерин көрсөтүү гана калды: Аяктоо баскычын чыкылдатыңыз. Долбоор түзүлдү, эми анын түзүмүн көрө алабыз: IDEA биз үчүн Maven куруу тутумун жайылтуу дескрипторун - pom.xml жана негизги тиркеме классын түздү:RestExampleApplication
. Бул жерде алардын codeу:
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.javarush.lectures</groupId>
<artifactId>rest_example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>rest_example</name>
<description>REST example project</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
RestExampleApplication:
@SpringBootApplication
public class RestExampleApplication {
public static void main(String[] args) {
SpringApplication.run(RestExampleApplication.class, args);
}
}
REST функциясын түзүү
Биздин колдонмо кардарларды башкарат. Ошентип, биринчи нерсе, биз кардар субъект түзүү болуп саналат. Бул POJO классы болот.model
Пакеттин ичинде пакет түзөлү com.javarush.lectures.rest_example
. Пакеттин ичинде model
класс түзөлү Client
:
public class Client {
private Integer id;
private String name;
private String email;
private String phone;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
Кызмат кардар боюнча CRUD операцияларын ишке ашырат. Кийинки кадам - бул операцияларды ишке ашыра турган кызматты түзүү. Пакетте com.javarush.lectures.rest_example
биз пакет түзөбүз service
, анын ичинде интерфейс түзөбүз ClientService
. Бул жерде комментарийлер менен интерфейс codeу:
public interface ClientService {
/**
* Создает нового клиента
* @param client - клиент для создания
*/
void create(Client client);
/**
* returns список всех имеющихся клиентов
* @return список клиентов
*/
List<client> readAll();
/**
* returns клиента по его ID
* @param id - ID клиента
* @return - an object клиента с заданным ID
*/
Client read(int id);
/**
* Обновляет клиента с заданным ID,
* в соответствии с переданным клиентом
* @param client - клиент в соответсвии с которым нужно обновить данные
* @param id - id клиента которого нужно обновить
* @return - true если данные были обновлены, иначе false
*/
boolean update(Client client, int id);
/**
* Удаляет клиента с заданным ID
* @param id - id клиента, которого нужно удалить
* @return - true если клиент был удален, иначе false
*/
boolean delete(int id);
}
Андан кийин биз бул интерфейстин ишке ашыруусун түзүшүбүз керек. Эми ал кардар репозиторийинин ролун аткарат Map<Integer, Client>
. Картанын ачкычы кардар идентификатору болот, ал эми маани кардар өзү болот. Бул маалымат базасы менен иштөөнүн өзгөчөлүктөрү менен мисалды ашыкча жүктөбөш үчүн жасалган. Бирок, келечекте биз чыныгы маалымат базасын туташтыруу мүмкүн болгон интерфейстин дагы бир ишке ашырууну жаза алабыз. Пакетте service
интерфейстин ишке ашырылышын түзөбүз ClientService
:
@Service
public class ClientServiceImpl implements ClientService {
// Хранorще клиентов
private static final Map<Integer, Client> CLIENT_REPOSITORY_MAP = new HashMap<>();
// Переменная для генерации ID клиента
private static final AtomicInteger CLIENT_ID_HOLDER = new AtomicInteger();
@Override
public void create(Client client) {
final int clientId = CLIENT_ID_HOLDER.incrementAndGet();
client.setId(clientId);
CLIENT_REPOSITORY_MAP.put(clientId, client);
}
@Override
public List<Client> readAll() {
return new ArrayList<>(CLIENT_REPOSITORY_MAP.values());
}
@Override
public Client read(int id) {
return CLIENT_REPOSITORY_MAP.get(id);
}
@Override
public boolean update(Client client, int id) {
if (CLIENT_REPOSITORY_MAP.containsKey(id)) {
client.setId(id);
CLIENT_REPOSITORY_MAP.put(id, client);
return true;
}
return false;
}
@Override
public boolean delete(int id) {
return CLIENT_REPOSITORY_MAP.remove(id) != null;
}
}
Аннотация @Service
Жазга бул класстын кызмат экенин айтат. Бул колдонмонун кээ бир бизнес логикасы ишке ашырылган класстын өзгөчө түрү. Кийинчерээк, бул annotationнын аркасында, Жаз бизге көз карандылык инъекциясынын жардамы менен керектүү жерлерде бул класстын үлгүсүн берет. Эми контроллерди түзүүгө убакыт келди. Биз акыркы чекиттер (URI) үчүн кардар суроо-талаптарын иштетүү логикасын ишке ашырган атайын класс. Түшүнүктүү болушу үчүн, биз бул классты бөлүктөргө бөлөбүз. Биринчиден, класстын өзүн түзүп, ага көз карандылыкты киргизели ClientService
:
@RestController
public class ClientController {
private final ClientService clientService;
@Autowired
public ClientController(ClientService clientService) {
this.clientService = clientService;
}
}
Аннотацияларды тактап көрөлү: @RestController - Жазга бул класс REST контроллери экенин айтат. Ошол. бул класс кардарлардын суроо-талаптарын иштеп чыгуу логикасын ишке ашырат @Autowired - Жазга бул жерге көз карандылыкты киргизүү керек экенин айтат. Биз интерфейсти конструкторго өткөрүп беребиз ClientService
. Биз бул кызматтын ишке ашырылышын мурда annotation менен белгилегенбиз @Service
, эми Spring бул ишке ашыруунун мисалын контроллер конструкторуна өткөрүп бере алат. Андан кийин, биз CRUD операцияларын иштетүү үчүн ар бир контроллердин ыкмасын этап-этабы менен ишке ашырабыз. Келгиле, түзүү операциясынан баштайлы. Бул үчүн, келгиле, бир ыкма жазалы create
:
@PostMapping(value = "/clients")
public ResponseEntity<?> create(@RequestBody Client client) {
clientService.create(client);
return new ResponseEntity<>(HttpStatus.CREATED);
}
Келгиле, бул ыкманы карап көрөлү: @PostMapping(value = "/clients")
- бул жерде бул ыкма POST суроо-талаптарын /кардарлар дарегине иштетет дегенди билдирет.Метод кайтарып берет ResponseEntity<?>
. ResponseEntity
- жоопторду кайтаруу үчүн атайын класс. Аны колдонуу менен биз кийинчерээк HTTP статус codeун кардарга кайтара алабыз. Метод параметрди алат @RequestBody Client client
, бул параметрдин мааниси сурамдын денесинен алмаштырылат. Бул тууралуу реферат айтылат @RequestBody
. Методдун корпусунун ичинде биз мурда түзүлгөн сервисте түзүү ыкмасын чакырабыз жана аны параметрлерде кабыл алынган кардар контроллерине өткөрүп беребиз. ResponseEntity
Андан кийин биз жаңы an object түзүү жана ага талап кылынган enum маанисин берүү менен түзүлгөн 201 статусун кайтарабыз HttpStatus
. Андан кийин, биз операцияны ишке ашырабыз Read
: Биринчиден, биз бардык жеткorктүү кардарлардын тизмесин алуу операциясын ишке ашырабыз:
@GetMapping(value = "/clients")
public ResponseEntity<List<Client>> read() {
final List<Client> clients = clientService.readAll();
return clients != null && !clients.isEmpty()
? new ResponseEntity<>(clients, HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Анализди баштайлы: @GetMapping(value = "/clients")
- баары annotationга окшош @PostMapping
, азыр гана биз GET сурамдарын иштетип жатабыз. Бул жолу биз кайтып келебиз ResponseEntity<List<Client>>
, бул жолу гана, HTTP статусунан тышкары, кардарлардын тизмеси боло турган жооп органын да кайтарабыз. Жазгы REST контроллерлорунда, бардык POJO an objectтери, ошондой эле жооп органдары катары кайтарылган POJO an objectтеринин коллекциялары, эгерде башкасы ачык көрсөтүлбөсө, автоматтык түрдө JSONге сериялаштырылат. Бул бизге абдан туура келет. Методдун ичинде, биздин кызматты колдонуп, биз бардык кардарлардын тизмесин алабыз. ResponseEntity
Андан кийин, тизме нөл же бош эмес болсо, классты колдонуу менен кардарлардын тизмесин жана HTTP статусун 200 OK кайтарабыз . Болбосо, биз жөн гана HTTP статусун кайтарабыз 404 Табылган жок. Андан кийин, биз кардарды анын ID боюнча кабыл алуу мүмкүнчүлүгүн ишке ашырабыз:
@GetMapping(value = "/clients/{id}")
public ResponseEntity<Client> read(@PathVariable(name = "id") int id) {
final Client client = clientService.read(id);
return client != null
? new ResponseEntity<>(client, HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Жаңы нерсе, бизде азыр жол өзгөрмөсү бар. URIда аныкталган өзгөрмө. value = "/clients/{id}"
. Биз аны тармал кашаа менен көрсөттүк. Ал эми методдун параметрлеринде биз аны int
annotationны колдонуп өзгөрмө катары кабыл алабыз @PathVariable(name = "id")
. Бул ыкма форманын uri сурамдарын кабыл алат /clients/{id}
, анын ордуна {id}
каалаган сандык маани болушу мүмкүн. Бул маани кийинчерээк өзгөрмөгө int id
— метод параметрине өтөт. Денеде биз Client
кызматыбызды колдонуп an objectти алабыз жана кабыл алабыз id
. Андан кийин, тизмеге окшоштук боюнча, биз 200 OK статусун жана an objectтин өзүн Client
, же жөн эле 404 Табылган эмес статусун кайтарабыз, эгерде id
системада бул кардар жок болсо. Эки операцияны ишке ашыруу калды - Жаңыртуу жана Өчүрүү. Бул ыкмалардын codeу:
@PutMapping(value = "/clients/{id}")
public ResponseEntity<?> update(@PathVariable(name = "id") int id, @RequestBody Client client) {
final boolean updated = clientService.update(client, id);
return updated
? new ResponseEntity<>(HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
@DeleteMapping(value = "/clients/{id}")
public ResponseEntity<?> delete(@PathVariable(name = "id") int id) {
final boolean deleted = clientService.delete(id);
return deleted
? new ResponseEntity<>(HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
Бул методдордо жаңы эч нерсе жок, андыктан биз кеңири сүрөттөөнү өткөрүп жиберебиз. Айта кетүүчү бир гана нерсе, метод update
PUT сурамдарын (annotation @PutMapping
) иштетет, ал эми метод delete
DELETE сурамдарын (annotation DeleteMapping
) иштетет. Бул жерде толук контроллер codeу болуп саналат:
@RestController
public class ClientController {
private final ClientService clientService;
@Autowired
public ClientController(ClientService clientService) {
this.clientService = clientService;
}
@PostMapping(value = "/clients")
public ResponseEntity<?> create(@RequestBody Client client) {
clientService.create(client);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@GetMapping(value = "/clients")
public ResponseEntity<List<Client>> read() {
final List<client> clients = clientService.readAll();
return clients != null && !clients.isEmpty()
? new ResponseEntity<>(clients, HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
@GetMapping(value = "/clients/{id}")
public ResponseEntity<Client> read(@PathVariable(name = "id") int id) {
final Client client = clientService.read(id);
return client != null
? new ResponseEntity<>(client, HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
@PutMapping(value = "/clients/{id}")
public ResponseEntity<?> update(@PathVariable(name = "id") int id, @RequestBody Client client) {
final boolean updated = clientService.update(client, id);
return updated
? new ResponseEntity<>(HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
@DeleteMapping(value = "/clients/{id}")
public ResponseEntity<?> delete(@PathVariable(name = "id") int id) {
final boolean deleted = clientService.delete(id);
return deleted
? new ResponseEntity<>(HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
}
Натыйжада, биздин долбоордун структурасы төмөнкүдөй болот:
Ишке киргизүү жана сыноо
main
Биздин колдонмону иштетүү үчүн класстагы методду иштетиңиз RestExampleApplication
. Жана RESTful веб-кызматтарын сыноо үчүн жаңы программалык камсыздоону жүктөп алышыңыз керек) Чындыгында GET суроо-талаптарын кадимки браузерден жөнөтүү оңой, бирок POST, PUT жана DELETE үчүн кадимки браузер жетишсиз. Кабатыр болбоңуз: сиз каалаган HTTP сурамдарын жөнөтүү үчүн Почтачыны колдоно аласыз. Сиз бул жерден жүктөп алсаңыз болот . Жүктөп алып, орноткондон кийин биз колдонмобузду сынап баштайбыз. Бул үчүн, программаны ачып, жаңы суроо түзүңүз: Жогорку сол бурчтагы Жаңы баскычын чыкылдатыңыз. Андан кийин, Суранычты тандаңыз: Кийинки, ага ат берип, сактаңыз. Эми serverге POST суроо-талапты жөнөтүп, биринчи кардарды түзүүгө аракет кылалы: Биз бир нече кардарларды ушундай жол менен түзөбүз. Андан кийин биз сурамдын түрүн GETге өзгөртүп, serverге жөнөтөбүз:
Жалпы жыйынтыктар
Куттуктайбыз: биз REST темасын толук чагылдырдык. Бардык материалдар көлөмдүү болуп чыкты, бирок биз сиз үчүн пайдалуу болот деп үмүттөнөбүз:-
Биз REST деген эмне экенин билдик.
-
Биз RESTтин тарыхы менен тааныштык.
-
Бул архитектуралык стилдин чектөөлөрү жана принциптери жөнүндө сүйлөштүк:
- архитектураны кардар-server моделине жеткирүү;
- шарттын жоктугу;
- кэштөө;
- интерфейстин бирдейлиги;
- катмарлар;
- талап боюнча code (кошумча чектөө).
-
Биз REST берген артыкчылыктарды карап чыктык
-
HTTP протоколун колдонуу менен server менен кардар бири-бири менен кантип иштешерин деталдуу карап чыктык.
-
Келгиле, суроо-талаптарды жана жоопторду кененирээк карап көрөлү. Алардын тетиктери демонтаждалган.
-
Акыры, биз практикага өтүп, Spring Boot программасына өзүбүздүн кичинекей RESTful тиркемебизди жаздык. Ал тургай, биз Postman программасын колдонуп, аны кантип сынап көрүүнү үйрөндүк.
Үй тапшырма
Төмөнкүлөрдү байкап көрүңүз:- Жогорудагы сүрөттөмөдөн кийин, өзүңүздүн Spring Boot долбооруңузду түзүңүз жана анда лекциядагыдай логиканы ишке ашырыңыз. Баарын 1де 1 кайталаңыз.
- Аны ишке киргизиңиз. колдонмо.
- Почтачыны (же суроо-талаптарды жөнөтүү үчүн башка куралды, атүгүл curl) жүктөп алып, орнотуңуз.
- POST жана GET суроо-талаптарын лекцияда айтылгандай эле текшериңиз.
- PUT жана DELETE сурамдарын өзүңүз текшериңиз.
GO TO FULL VERSION