實戰SpringCloud響應式微服務系列教程(第八章)構建響應式RESTful服務


本文為實戰SpringCloud響應式微服務系列教程第八章,講解構建響應式RESTful服務。建議沒有之前基礎的童鞋,先看之前的章節,章節目錄放在文末。

1.使用springboot2.1.4構建RESTful風格服務

Springboot的設計是用來簡化Spring應用程序的初始搭建和開發過程,為了實現這種簡化效果,Springboot繼承了眾多第三方庫,並大量使用約定優於配置的設計理念,通過特定的方式使得開發人員不再需要定義繁雜而且多余的配置內容。

1.1基於Springboot的第一個RESTful服務

微服務架構推崇采用RESTful風格實現服務之間的交互。關於RESTful,很多開發人員在知識體系上的一些誤解和不足。我們先對RESTful風格做一個簡單的介紹,然后詳細闡述使用SpringBoot構建單個RESTful服務的過程。

(1)RESTful風格簡介

REST提出了一組建構約束條件和原則,滿足這些約束條件和原則的設計風格就是RESTful。

現實世界中的事物都可以被認為一種資源,我們可以根據這些約束條件和原則設計以資源為中心的服務。REST中最重要的一條原則就是客戶端和服務器之間的交互無狀態性。

從客戶端到服務器的每個請求都必須包含理解該請求所必需的信息,無狀態請求可以由任何可用服務實現響應,十分適合微服務架構的運行環境。所以RESTful代表的實際上是一種風格,而不是一種設計和架構模式,更不是一種具體的技術體系。

關於RESTful另一個比較容易忽視的核心概念是HATEOAS(Hypermedia as the Engine of Application State,基於超媒體的應用狀態引擎)。要解釋HATEOAS的概念,先要解釋什么是超媒體。

我們已經知道什么是超鏈接以及什么是超文本,其中超文本的特有優勢是擁有超鏈接。如果把超鏈接映入到多媒體中,就得到了超媒體。因此關鍵要素還是超鏈接。使用過超媒體作為應用引擎狀態,意思就是應用引擎的狀態變更由客戶端訪問不同的超媒體資源來驅動。

使用HATEOAS表現服務請求響應的風格如下,可以看到這里多了_links屬性,其中有一個self.href鏈接指向當前user資源。

GET http://api.example.com/users/tianyalan
Content-type:application/json
{
   _links:{
      self:{
         href:"/users/tianyalan"
       }
   }
  "id":"tianyalan",
   "name":"tianyalan",
   "email":"tianyalan@email.com"
}

 

HATEOAS在spring boot和spring cloud中應用也非常廣泛,例如springboot提供了應用監控組件Actuator,通過Actuator可以獲取springboot應用程序當前的運行狀態,我們將在后續章節中詳細介紹Actuator組件。

Actuator組件對外暴露的也是一些http端點,訪問這些端點返回的數據跟常見的RESTful風格有所不同,這就是HATEOAS風格,所以可以參考相關資料進一步了解。

(2)引入spring-boot-starter-web工程

spring boot提供了一系列starter工程來簡化各組件之間的依賴關系。

例如在springboot中開發基於RESTful風格的端點時,通常會引入spring-boot-starter-web這個工程,而打開這個工程會發現里面實際上只定義了如下所示的一些pom依賴,其中包括所有我們能夠預見到的組件,例如非常經典的spring-web,spring-webmvc組件,可以看到spring-boot-starter-web還是基於這兩個組件構建web請求響應流程的。

另外還包含了基於JSON序列化和反序列化的jackson-databind組件,以及啟動內置tomcat服務器的spring-boot-starter-tomcat組件。

  • org.springframework.boot:spring-boot-starter
  • org.springframework.boot:spring-boot-starter-tomcat
  • org.springframework.boot:spring-boot-starter-validation
  • org.springframework.boot:spring-web
  • org.springframework.boot:spring-webmvc
  • org.fasterxml.jackson.core:jackson-databind

引入spring-boot-starter-web就像引入一個普通的maven依賴一樣,代碼如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

 

一旦spring-boot-starter-web組件引入完畢,我們就可以充分利用springboot的自動裝配機制開發單個服務。

(3)Application類

使用springboot的首要條件是構建一個Application啟動類。代碼如下:

@SpringBootApplication
public class SoulApplication {
    public static void main(String[] args) {
        SpringApplication.run(SoulApplication.class, args);
    }
}

 

結構比較固化。

顯然以上代碼關鍵的是@SpringBootApplication注解。springboot使用@SpringBootApplication注解來告訴spring容器具備該注解的類是整個spring容器中所有javaBean對象的入口,而具備該注解的類在springboot中就是Application類。

在上面代碼中,SoulApplication類就是整個容器的Application類。

@SpringBootApplication注解在指定Application類的同時,還會自動掃描與當前類同級以及子包下的@Component@Service@Repository@Controller@Entity等注解,並把這些注解對應的類轉換為Bean對象全部加載到Spring容器中管理起來。

@SpringBootApplication注解的定義如下,我們可以看到該注解實際上由三個注解組合而成,分別是@Configuration@EnableAutoConfigguration@ComponentScan

@Target(ElementType.TYPE)
@Retenation(RetentionPolicy.PUNTIME)
@Documented
@Inherited
@Configuration
@EnableAutoConfigguration
@ComponentScan
public @interface SpringBootApplication

 

在Spring 中@Configuration比較常見,提供javaConfig配置類實現。而@ComponentScan則掃描@Component等注解,幫相關的javaBean定義批量加載到IOC容器中。@EnableAutoConfigguration最終會使用JDK提供的SPI機制來實現類的動態加載。

關於@EnableAutoConfigguration注解更多的可以參考相關的資料。

我們還注意到在上面的代碼示例中包含一個main函數並執行了ApplicationContext對象,我們可以根據需求對該ApplicationContext對象做響應處理。

(4)Controller類

Application類提供了Springboot程序的入口,相當於應用程序擁有了最基本的骨架。接下來我們就可以添加各種業務相關的訪問入口,表現在RESTful風格上也就是一系列的Controller類所代表的的HTTP端點。

這里的Controller和springMvc的Controller在概念上是一致的。最簡單的Controller如下:

@RestController
public class HelloController{
     @GetMapping("/")
     public String index(){
          return "Hello Spring Boot";
     }
}

 

以上代碼包含了@RestController@GetMapping("/")兩個注解。我們知道在springMvc中包含了@Controller注解用來表示當前類是一個servlet。

@RestController繼承了@Controller,它告訴Springboot這是一個基於RESTful風格的HTTP端點,並會自動使用JSON實現HTTP請求和響應的序列化和反序列化操作。至於@GetMapper類似@RequestMapping,指定請求方式為GET。這里不做多余介紹。

以下代碼展示了一個典型的Controller,在Controller中通過靜態的業務代碼完成了根據商品編號,獲取商品信息的業務流程。

這里用到了兩層Mapping注解,在服務層級定義了服務的版本和路徑,分別為v1和products;而在操作級別有定義了HTTP請求方法的具體路徑及參數信息。

@RestController
@RequestMapping("/v1/products")
public class Productontroller{
     @GetMapping("/{productCode}")
     public Product getProduct(@PathVariable String productCode){
          Product product = new Product();
          product .setId(1L);
   product .setPrice(100F);
   product .setProductCode("product001");
   product .setProductName("product");
   return product;
     }
}

 

系列章節目錄

實戰SpringCloud響應式微服務系列教程(第一章)

實戰SpringCloud響應式微服務系列教程(第二章)

實戰SpringCloud響應式微服務系列教程(第三章)

實戰SpringCloud響應式微服務系列教程(第四章)

實戰SpringCloud響應式微服務系列教程(第五章)

實戰SpringCloud響應式微服務系列教程(第六章)

實戰SpringCloud響應式微服務系列教程(第七章)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM