SlideShare a Scribd company logo
Spring Data REST
と
Spring Cloud Contract
Tagbangers, Inc.
#sf_25 #アンケート
© Tagbangers, Inc. 1
自己紹介
小川岳史
Spring Lover 10 years
山﨑大
わさもん
© Tagbangers, Inc. 2
本日のメニュー
• 背景
• Spring Data REST
• HATEOAS
• Spring Cloud Contract
• CDC
• Pact
© Tagbangers, Inc. 3
背景
• SPA 時代
• よりリッチな UI 表現のために Thymeleaf から Angular などへ
• ビジネスロジックの実装が UI 側にも必要なり…
Browser
Application • ビジネスロジック
• CRUD
Browser
Application • ビジネスロジック
• CRUD
• ビジネスロジック
DB
DB
© Tagbangers, Inc. 4
工程やチーム構成の変化
BackendFrontend
ex. Angular ex. Spring Boot
Frontend Team Backend Team
User
repo repo
CI/CDCI/CD
code
push
code
push
artifactartifact
別々のデプロイ環境
別々のチーム
別々のレポジトリ
別々のリリースサイクル
© Tagbangers, Inc. 5
どの URI にアクセスすれば
いいの?
どんなフォーマットでデー
タが取得できるの?
更新できる条件ってなんな
の??
そこで発生してきた課題
開発初期段階
© Tagbangers, Inc. 6
API の仕様が変更されて UI がバグったんだけど〜
そこで発生してきた課題
リリース後のバージョンアップで
© Tagbangers, Inc. 7
解決策
どの URI にアクセスすればいいの?
どんなフォーマットでデータが
取得できるの?
更新できる条件ってなんなの??
API の仕様が変更されて
UI がバグったんだけど〜
Spring Data REST
Spring エコシステムをフル活用!
標準化 + 自動生成 別々に進化できる仕組み
Spring Cloud Contract
Spring Data REST
✓ 標準化 + 自動生成
© Tagbangers, Inc. 9
残念な実装
class ReservationService {
Reservation getReservation(long id) {
return this.reservationRepository.findById(id);
}
Reservation createReservation(Reservation reservation) {
return this.reservationRepository.save(reservation);
}
}
© Tagbangers, Inc. 10
Spring Data REST とは
Entity
GET /items
GET /items/search
GET / items/1
POST /items
PUT /items/1
PATCH /items/1
DELETE /items/1
…
Item ItemRepository
REST スタイルな API エンドポイント
URL 設計に迷わない
Repository
© Tagbangers, Inc. 11
Spring Data REST の始め方
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
© Tagbangers, Inc. 12
Entity
Repository
@Entity
public class Order {
private Long id;
private Location location;
private LocalDateTime orderedDate;
private Status status;
}
public interface OrderRepository
extends PagingAndSortingRepository<Order, Long> {
}
© Tagbangers, Inc. 13
. ____ _ __ _ _
/ / ___'_ __ _ _(_)_ __ __ _    
( ( )___ | '_ | '_| | '_ / _` |    
/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |___, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.6.RELEASE)
...
Mapped "{[/ || ],methods=[HEAD],produces=[application/hal+json || application/json]}" ...
Mapped "{[/ || ],methods=[GET],produces=[application/hal+json || application/json]}" ...
Mapped "{[/ || ],methods=[OPTIONS],produces=[application/hal+json || application/json]}" ...
Mapped "{[/{repository}],methods=[OPTIONS],produces=[application/hal+json || application/json]}" ...
Mapped "{[/{repository}],methods=[HEAD],produces=[application/hal+json || application/json]}" ...
Mapped "{[/{repository}],methods=[GET],produces=[application/hal+json || application/json]}" ...
Mapped "{[/{repository}],methods=[GET],produces=[application/x-spring-data-compact+json || text/uri-list]}" ...
Mapped "{[/{repository}],methods=[POST],produces=[application/hal+json || application/json]}" ...
Mapped "{[/{repository}/{id}],methods=[OPTIONS],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/{id}],methods=[HEAD],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/{id}],methods=[GET],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/{id}],methods=[PUT],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/{id}],methods=[PATCH],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/{id}],methods=[DELETE],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/{id}/{property}],methods=[GET],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/{id}/{property}/{propertyId}],methods=[GET],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/{id}/{property}],methods=[DELETE],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/{id}/{property}],methods=[GET],produces=[application/x-spring-data-compact+json || text/uri-list]}"
Mapped "{[/{repository}/{id}/{property}],methods=[PATCH || PUT || POST],consumes=[application/json || application/x-spring-data-compact+json || text/uri-list], ...
Mapped "{[/{repository}/{id}/{property}/{propertyId}],methods=[DELETE],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/search],methods=[OPTIONS],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/search],methods=[HEAD],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/search],methods=[GET],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/search/{search}],methods=[GET],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/search/{search}],methods=[GET],produces=[application/x-spring-data-compact+json]}"
Mapped "{[/{repository}/search/{search}],methods=[OPTIONS],produces=[application/hal+json || application/json]}"
Mapped "{[/{repository}/search/{search}],methods=[HEAD],produces=[application/hal+json || application/json]}"
Mapped "{[/profile],methods=[OPTIONS]}"
Mapped "{[/profile],methods=[GET]}"
Mapped "{[/profile/{repository}],methods=[GET],produces=[application/alps+json || */*]}"
Mapped "{[/profile/{repository}],methods=[OPTIONS],produces=[application/alps+json]}"
Mapped "{[/profile/{repository}],methods=[GET],produces=[application/schema+json]}"
Mapped "{[/ || ],methods=[GET],produces=[text/html]}"
Mapped "{[/browser],methods=[GET]}"
自動的にエンドポイントが登録されている
/repository…
© Tagbangers, Inc. 14
{
"firstName" : "Frodo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
}
}
}
$ curl http://localhost:8080/people/1
LINK 部
DATA 部
© Tagbangers, Inc. 15
HATEOAS
• Hypermedia as the Engine of Application State
• データ部の他にリンク情報が追加され、関連するリソースをたどることができる
• Spring Data REST のリクエスト・レスポンスボディ部のフォーマットは HATEOAS に準拠
• Spring HATEOAS は独立したライブラリでこれだけ使うこともできる
© Tagbangers, Inc. 16
フロント側で ID を取り出して個別に
URL を組み立てる必要がない
ページング情報も
$ curl http://localhost:8080/people
{
"_links" : {
"self" : {
"href" : "http://localhost:8080/people{?page,size,sort}",
"templated" : true
},
"search" : {
"href" : "http://localhost:8080/people/search"
}
},
"_embedded" : {
"persons" : [ {
"firstName" : "Frodo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
}
}
} ]
},
"page" : {
"size" : 20,
"totalElements" : 1,
"totalPages" : 1,
"number" : 0
}
}
HATEOAS にのっかることでボディ部の
フォーマットも悩まない
© Tagbangers, Inc. 17
{
"description": "iPhone",
"status": "IN_PROGRESS",
"_links": {
"self": {
"href": "http://localhost:8080/orders/4"
},
"orders": {
"href": "http://localhost:8080/orders"
},
"cancel": {
"href": "http://localhost:8080/orders/4/cancel"
},
"complete": {
"href": "http://localhost:8080/orders/4/complete"
}
}
if ( order.status == PENDING || order.status == PAID ) {
showCancelButton
}
© Tagbangers, Inc. 18
ビジネスロジックの流出を最小限
に
キャンセル判定
ロジック
キャンセル判定
ロジック
キャンセル判定
ロジック
© Tagbangers, Inc. 19
自動生成されて簡単!とはいえ…
• とにかく簡単だけど…
• Spring Data REST だけでは完成しない
• 基本的に CRUD のみ
• ビジネスロジックが必要な場合は拡張する
Controller
Service
Repository
Database
ここは自分で書く
Spring Data RESTが
よしなに
© Tagbangers, Inc. 20
Repository
Spring
Data
REST
@RepositoryRest
Controller
Service
@Controller
@RestController
Endpoint
Endpoint
Endpoint
Domain
Model
ビジネスロジックの実装パターン
EventHandler
© Tagbangers, Inc. 21
JSON Schema
• JSON Schema から TypeScript のコードの自動生成
TypescriptJson schema
自動生成
curl -H 'Accept:application/schema+json' http://localhost:8080/profile/reservations
{
"title" : "Reservation",
"properties" : {
"date" : {
"title" : "Date",
"readOnly" : false,
"type" : "string",
"format" : "date-time"
},
"name" : {
"title" : "Name",
"readOnly" : false,
"type" : "string"
}
},
"definitions" : { },
"type" : "object",
"$schema" : "http://json-schema.org/draft-04/schema#"
}
export type Date = string;
export type Name = string;
export interface Reservation {
date?: Date;
name?: Name;
[k: string]: any;
}
© Tagbangers, Inc. 22
Admin over Spring Data REST
User UI Admin UI
Spring
Data
REST
Manual
Impl
DB
© Tagbangers, Inc. 23
全文検索 over Spring Data REST
UI
Elastic
Search
Spring
Data
REST
Hibernate
Search
DB
Custom
Repository
Impl
© Tagbangers, Inc. 24
マルチテナント over Spring Data REST
UI
Spring
Data
REST
Repository DBHibernate
Spring
Security
Authentication
Event Listener
Filter
Tenant
© Tagbangers, Inc. 25
ポイント
 Spring Data REST を活用してボイラープレートコードを削減する
 REST や HATEOAS の流行りの仕様を活用する
チーム間のコミュニケーションをフォーマット的なことではなく、
よりビジネス的にフォーカスしたいポイントに絞る!!
© Tagbangers, Inc. 26
ポイント
BackendFrontend
ex. Angular ex. Spring Boot
Frontend Team Backend Team
User
repo repo
CI/CDCI/CD
code
push
code
push
artifactartifact
Spring Data REST
Spring HATEOAS
Spring Cloud Contract
でさくっと行う
Consumer Driven Contract
with Pact
別々に進化できる仕組み
© Tagbangers, Inc. 28
工程やチーム構成の変化
BackendFrontend
ex. Angular ex. Spring Boot
Frontend Team Backend Team
User
repo repo
CI/CDCI/CD
code
push
code
push
artifactartifact
別々のデプロイ環境
別々のチーム
別々のレポジトリ
別々のリリースサイクル
© Tagbangers, Inc. 29
Test Pyramid
https://martinfowler.com/bliki/TestPyramid.html
© Tagbangers, Inc. 30
モック に置き換える
HTTP
© Tagbangers, Inc. 31
モック に置き換える
その モック 意味がありますか?
• インターフェースは正しい??
• 連携するサービスが変更されたら?
• だれがメンテナンスするの?
© Tagbangers, Inc. 32
Micro service architecture
Microservice MicroserviceMicroservice
UI
Microservice
モックモックモックモックモックモックモックモック
© Tagbangers, Inc. 33
Spring Cloud Contract
Spring Cloud Contract is an
umbrella project holding
solutions that help users in
successfully implementing
the Consumer Driven
Contracts approach.
© Tagbangers, Inc. 34
Pact
Pact is a contract testing tool. Contract
testing is a way to ensure that services
(such as an API provider and a client) can
communicate with each other. Without
contract testing, the only way to know that
services can communicate is by using
expensive and brittle integration tests
© Tagbangers, Inc. 35
Contract
• 契約はインターフェース定義のようなもの
• API 仕様書の内容
• Provider が契約を守ることを約束する
Contract
Consumer
Consumer and provider are
both agreed with the sentence
below.. for example we agreed with
on the basis of the Provider’s REST
API, that is created hy
Provider
Test ✔
Test ✔
Spring Cloud Contract + Pact
で
Consumer Driven Contract
© Tagbangers, Inc. 37
CDC ステップ
1. テスト書く
2. Contract(Pact file) を自動生成
3. Pact Broker に Pact file を publish
Consumer
1. Pact Broker から Contract(Pact file) を取得
2. Test を自動生成(Spring Cloud Contract )
3. モック を自動生成(Spring Cloud Contract)
Provider
https://github.com/pact-foundation/pact_broker/wiki/Webhooks
© Tagbangers, Inc. 38
1. テストを書く
beforeAll ((done) => {
provider = new PactWeb({
consumer: ‘sample-client-tenant',
provider: ‘sapmle-server-tenant',
port: 1234,
host: '127.0.0.1'
});
});
前準備 1
© Tagbangers, Inc. 39
1. テストを書く
beforeAll((done) => {
provider.addInteraction({
uponReceiving: 'a request for hello',
withRequest: {
method: 'GET',
path: '/hello'
},
willRespondWith: {
status: 200,
headers: {
'Content-Type': 'application/hal+json;charset=UTF-8'
},
body: {
reply: 'Hello'
}
}
}).then(done, done.fail);
});
前準備 2
© Tagbangers, Inc. 40
1. テストを書く
it('should', (done) => {
const greetingService: GreetingService =
TestBed.get(GreetingTypeService);
greetingService.hello().subscribe(response => {
expect(response).toEqual({reply: 'Hello'});
done();
}, error => {
done.fail(error);
});
});
テスト
/hello に Get リクエスト
© Tagbangers, Inc. 41
CDC ステップ
1. テスト書く
2. Contract(Pact file) を自動生成
3. Pact Broker に Pact file を publish
1. Pact Broker から Contract(Pact file) を取得
2. Test を自動生成(Spring Cloud Contract )
3. モック を自動生成(Spring Cloud Contract)
Consumer
Provider
© Tagbangers, Inc. 42
2. Pact file ( Contract )
Pact file
...
"interactions": [
{
"description": "a request for hello",
"request": {
"method": "GET",
"path": "/hello"
},
"response": {
"status": 200,
"headers": {
"Content-Type":
"application/hal+json;charset=UTF-8"
...
© Tagbangers, Inc. 43
CDC ステップ
1. テスト書く
2. Contract(Pact file) を自動生成
3. Pact Broker に Pact file を publish
1. Pact Broker から Contract(Pact file) を取得
2. Test を自動生成(Spring Cloud Contract )
3. モック を自動生成(Spring Cloud Contract)
Contract を共有するためのアプリ
https://github.com/pact-foundation/pact_broker/wiki/Webhooks
Consumer
Provider
© Tagbangers, Inc. 44
Pact Broker
https://github.com/pact-foundation/pact_broker
© Tagbangers, Inc. 45
Pact Broker
https://github.com/pact-foundation/pact_broker
© Tagbangers, Inc. 46
CDC ステップ
1. テスト書く
2. Contract(Pact file) を自動生成
3. Pact Broker に Pact file を publish
1. Pact Broker から Contract(Pact file) を取得
2. Test を自動生成(Spring Cloud Contract )
3. モック を自動生成(Spring Cloud Contract)
https://github.com/pact-foundation/pact_broker/wiki/Webhooks
Consumer
Provider
© Tagbangers, Inc. 47
CDC ステップ
1. テスト書く
2. Contract(Pact file) を自動生成
3. Pact Broker に Pact file を publish
1. Pact Broker から Contract(Pact file) を取得
2. Test を自動生成(Spring Cloud Contract )
3. モック を自動生成(Spring Cloud Contract)
ビルド時にテストを生成 + テスト実行
https://github.com/pact-foundation/pact_broker/wiki/Webhooks
Consumer
Provider
© Tagbangers, Inc. 48
CDC ステップ
1. テスト書く
2. Contract(Pact file) を自動生成
3. Pact Broker に Pact file を publish
1. Pact Broker から Contract(Pact file) を取得
2. Test を自動生成(Spring Cloud Contract )
3. モック を自動生成(Spring Cloud Contract)
https://github.com/pact-foundation/pact_broker/wiki/Webhooks
Consumer
Provider
© Tagbangers, Inc. 49
CDC ステップ
1. テスト書く
2. Contract(Pact file) を自動生成
3. Pact Broker に Pact file を publish
1. Pact Broker から Contract(Pact file) を取得
2. Test を自動生成(Spring Cloud Contract )
3. モック を自動生成(Spring Cloud Contract)
成果物としてWireMockの定義ファイルができる
https://github.com/pact-foundation/pact_broker/wiki/Webhooks
Consumer
Provider
© Tagbangers, Inc. 50
APIが実装されたか知りたい
https://github.com/pact-foundation/pact_broker/wiki/Webhooks
Broker のステータス確認で対応状況を把握
© Tagbangers, Inc. 51
Pact Broker
https://github.com/pact-foundation/pact_broker
© Tagbangers, Inc. 52
破壊的な API の実装の変更
https://github.com/pact-foundation/pact_broker/wiki/Webhooks
テストが通らないので破壊的な変更だとわかる!
© Tagbangers, Inc. 53
使用されている API がわかる!
https://github.com/pact-foundation/pact_broker
まとめ
© Tagbangers, Inc. 55
まとめ
BackendFrontend
ex. Angular ex. Spring Boot
Frontend Team Backend Team
User
repo repo
CI/CDCI/CD
code
push
code
push
artifactartifact
Spring Data REST
Spring HATEOAS
Spring Cloud Contract

More Related Content

What's hot

基礎からのOAuth 2.0とSpring Security 5.1による実装
基礎からのOAuth 2.0とSpring Security 5.1による実装基礎からのOAuth 2.0とSpring Security 5.1による実装
基礎からのOAuth 2.0とSpring Security 5.1による実装
Masatoshi Tada
 
アーキテクチャから理解するPostgreSQLのレプリケーション
アーキテクチャから理解するPostgreSQLのレプリケーションアーキテクチャから理解するPostgreSQLのレプリケーション
アーキテクチャから理解するPostgreSQLのレプリケーション
Masahiko Sawada
 
Vault の鍵管理機構
Vault の鍵管理機構Vault の鍵管理機構
Vault の鍵管理機構
Katsuya Yamaguchi
 
An Internal of LINQ to Objects
An Internal of LINQ to ObjectsAn Internal of LINQ to Objects
An Internal of LINQ to Objects
Yoshifumi Kawai
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろうKota Mizushima
 
こわくない Git
こわくない Gitこわくない Git
こわくない Git
Kota Saito
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
Yuji Otani
 
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)
NTT DATA Technology & Innovation
 
SQLアンチパターン - ジェイウォーク
SQLアンチパターン - ジェイウォークSQLアンチパターン - ジェイウォーク
SQLアンチパターン - ジェイウォーク
ke-m kamekoopa
 
マルチテナントのアプリケーション実装〜実践編〜
マルチテナントのアプリケーション実装〜実践編〜マルチテナントのアプリケーション実装〜実践編〜
マルチテナントのアプリケーション実装〜実践編〜
Yoshiki Nakagawa
 
[Cloud OnAir] BigQuery で実現する Smart Analytics Platform 2019年10月24日 放送
[Cloud OnAir] BigQuery で実現する Smart Analytics Platform 2019年10月24日 放送[Cloud OnAir] BigQuery で実現する Smart Analytics Platform 2019年10月24日 放送
[Cloud OnAir] BigQuery で実現する Smart Analytics Platform 2019年10月24日 放送
Google Cloud Platform - Japan
 
C#でわかる こわくないMonad
C#でわかる こわくないMonadC#でわかる こわくないMonad
C#でわかる こわくないMonad
Kouji Matsui
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
NTT Communications Technology Development
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
Akihiro Suda
 
システムアーキテクト~My batis編~
システムアーキテクト~My batis編~システムアーキテクト~My batis編~
システムアーキテクト~My batis編~
Shinichi Kozake
 
継続的にテスト可能な設計を考える
継続的にテスト可能な設計を考える継続的にテスト可能な設計を考える
継続的にテスト可能な設計を考える
Atsushi Nakamura
 
PlantUML Plugin 紹介スライド
PlantUML Plugin 紹介スライドPlantUML Plugin 紹介スライド
PlantUML Plugin 紹介スライド
ChangeVision
 
[GKE & Spanner 勉強会] Cloud Spanner の技術概要
[GKE & Spanner 勉強会] Cloud Spanner の技術概要[GKE & Spanner 勉強会] Cloud Spanner の技術概要
[GKE & Spanner 勉強会] Cloud Spanner の技術概要
Google Cloud Platform - Japan
 
Spring Integration 超入門
Spring Integration 超入門Spring Integration 超入門
Spring Integration 超入門
Yasutaka Sugamura
 
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
NTT DATA Technology & Innovation
 

What's hot (20)

基礎からのOAuth 2.0とSpring Security 5.1による実装
基礎からのOAuth 2.0とSpring Security 5.1による実装基礎からのOAuth 2.0とSpring Security 5.1による実装
基礎からのOAuth 2.0とSpring Security 5.1による実装
 
アーキテクチャから理解するPostgreSQLのレプリケーション
アーキテクチャから理解するPostgreSQLのレプリケーションアーキテクチャから理解するPostgreSQLのレプリケーション
アーキテクチャから理解するPostgreSQLのレプリケーション
 
Vault の鍵管理機構
Vault の鍵管理機構Vault の鍵管理機構
Vault の鍵管理機構
 
An Internal of LINQ to Objects
An Internal of LINQ to ObjectsAn Internal of LINQ to Objects
An Internal of LINQ to Objects
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
 
こわくない Git
こわくない Gitこわくない Git
こわくない Git
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)
 
SQLアンチパターン - ジェイウォーク
SQLアンチパターン - ジェイウォークSQLアンチパターン - ジェイウォーク
SQLアンチパターン - ジェイウォーク
 
マルチテナントのアプリケーション実装〜実践編〜
マルチテナントのアプリケーション実装〜実践編〜マルチテナントのアプリケーション実装〜実践編〜
マルチテナントのアプリケーション実装〜実践編〜
 
[Cloud OnAir] BigQuery で実現する Smart Analytics Platform 2019年10月24日 放送
[Cloud OnAir] BigQuery で実現する Smart Analytics Platform 2019年10月24日 放送[Cloud OnAir] BigQuery で実現する Smart Analytics Platform 2019年10月24日 放送
[Cloud OnAir] BigQuery で実現する Smart Analytics Platform 2019年10月24日 放送
 
C#でわかる こわくないMonad
C#でわかる こわくないMonadC#でわかる こわくないMonad
C#でわかる こわくないMonad
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
システムアーキテクト~My batis編~
システムアーキテクト~My batis編~システムアーキテクト~My batis編~
システムアーキテクト~My batis編~
 
継続的にテスト可能な設計を考える
継続的にテスト可能な設計を考える継続的にテスト可能な設計を考える
継続的にテスト可能な設計を考える
 
PlantUML Plugin 紹介スライド
PlantUML Plugin 紹介スライドPlantUML Plugin 紹介スライド
PlantUML Plugin 紹介スライド
 
[GKE & Spanner 勉強会] Cloud Spanner の技術概要
[GKE & Spanner 勉強会] Cloud Spanner の技術概要[GKE & Spanner 勉強会] Cloud Spanner の技術概要
[GKE & Spanner 勉強会] Cloud Spanner の技術概要
 
Spring Integration 超入門
Spring Integration 超入門Spring Integration 超入門
Spring Integration 超入門
 
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
 

Similar to Spring data-rest-and-spring-cloud-contract

エンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSエンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSAyumi Goto
 
Azure Search クックブック
Azure Search クックブックAzure Search クックブック
Azure Search クックブック
Kazuyuki Miyake
 
Microsoft Graphことはじめ クエリパラメータ編
Microsoft Graphことはじめ クエリパラメータ編Microsoft Graphことはじめ クエリパラメータ編
Microsoft Graphことはじめ クエリパラメータ編
DevTakas
 
Develop Web Application with Node.js + Express
Develop Web Application with Node.js + ExpressDevelop Web Application with Node.js + Express
Develop Web Application with Node.js + Express
Akinari Tsugo
 
GraphQL入門 (AWS AppSync)
GraphQL入門 (AWS AppSync)GraphQL入門 (AWS AppSync)
GraphQL入門 (AWS AppSync)
Amazon Web Services Japan
 
APIMeetup 20170329_ichimura
APIMeetup 20170329_ichimuraAPIMeetup 20170329_ichimura
APIMeetup 20170329_ichimura
Tomohiro Ichimura
 
OSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニックOSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニック
庸介 高橋
 
Microsoft Graph APIを活用した社内アプリケーション開発
Microsoft Graph APIを活用した社内アプリケーション開発Microsoft Graph APIを活用した社内アプリケーション開発
Microsoft Graph APIを活用した社内アプリケーション開発
Yuki Hattori
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回Naoyuki Yamada
 
ASP.NET シングル ページ アプリケーション (SPA) 詳説
ASP.NET シングル ページ アプリケーション (SPA) 詳説ASP.NET シングル ページ アプリケーション (SPA) 詳説
ASP.NET シングル ページ アプリケーション (SPA) 詳説Akira Inoue
 
ADO.NETとORMとMicro-ORM -dapper dot netを使ってみた
ADO.NETとORMとMicro-ORM -dapper dot netを使ってみたADO.NETとORMとMicro-ORM -dapper dot netを使ってみた
ADO.NETとORMとMicro-ORM -dapper dot netを使ってみた
Narami Kiyokura
 
Scala が支える医療系ウェブサービス #jissenscala
Scala が支える医療系ウェブサービス #jissenscalaScala が支える医療系ウェブサービス #jissenscala
Scala が支える医療系ウェブサービス #jissenscala
Kazuhiro Sera
 
MapR 5.2: MapR コンバージド・コミュニティ・エディションを使いこなす
MapR 5.2: MapR コンバージド・コミュニティ・エディションを使いこなすMapR 5.2: MapR コンバージド・コミュニティ・エディションを使いこなす
MapR 5.2: MapR コンバージド・コミュニティ・エディションを使いこなす
MapR Technologies Japan
 
PyConAPAC2023 ワークフローエンジン Apache Airflowを用いた 大規模データパイプライン構築と改善
PyConAPAC2023 ワークフローエンジン  Apache Airflowを用いた 大規模データパイプライン構築と改善PyConAPAC2023 ワークフローエンジン  Apache Airflowを用いた 大規模データパイプライン構築と改善
PyConAPAC2023 ワークフローエンジン Apache Airflowを用いた 大規模データパイプライン構築と改善
株式会社MonotaRO Tech Team
 
Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方
Shinsuke Sugaya
 
BCPに活かせ!一撃 CloudFormation
BCPに活かせ!一撃 CloudFormationBCPに活かせ!一撃 CloudFormation
BCPに活かせ!一撃 CloudFormation
真吾 吉田
 
Spring Framework / Boot / Data 徹底活用 〜Spring Data Redis 編〜
Spring Framework / Boot / Data 徹底活用  〜Spring Data Redis 編〜Spring Framework / Boot / Data 徹底活用  〜Spring Data Redis 編〜
Spring Framework / Boot / Data 徹底活用 〜Spring Data Redis 編〜
Naohiro Yoshida
 
初めてのPadrino
初めてのPadrino初めてのPadrino
初めてのPadrino
Takeshi Yabe
 
WordBench京都12月、WordCampUSからのWP REST APIな話
WordBench京都12月、WordCampUSからのWP REST APIな話WordBench京都12月、WordCampUSからのWP REST APIな話
WordBench京都12月、WordCampUSからのWP REST APIな話
Hidetaka Okamoto
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用
Yatabe Terumasa
 

Similar to Spring data-rest-and-spring-cloud-contract (20)

エンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSエンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJS
 
Azure Search クックブック
Azure Search クックブックAzure Search クックブック
Azure Search クックブック
 
Microsoft Graphことはじめ クエリパラメータ編
Microsoft Graphことはじめ クエリパラメータ編Microsoft Graphことはじめ クエリパラメータ編
Microsoft Graphことはじめ クエリパラメータ編
 
Develop Web Application with Node.js + Express
Develop Web Application with Node.js + ExpressDevelop Web Application with Node.js + Express
Develop Web Application with Node.js + Express
 
GraphQL入門 (AWS AppSync)
GraphQL入門 (AWS AppSync)GraphQL入門 (AWS AppSync)
GraphQL入門 (AWS AppSync)
 
APIMeetup 20170329_ichimura
APIMeetup 20170329_ichimuraAPIMeetup 20170329_ichimura
APIMeetup 20170329_ichimura
 
OSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニックOSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニック
 
Microsoft Graph APIを活用した社内アプリケーション開発
Microsoft Graph APIを活用した社内アプリケーション開発Microsoft Graph APIを活用した社内アプリケーション開発
Microsoft Graph APIを活用した社内アプリケーション開発
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回
 
ASP.NET シングル ページ アプリケーション (SPA) 詳説
ASP.NET シングル ページ アプリケーション (SPA) 詳説ASP.NET シングル ページ アプリケーション (SPA) 詳説
ASP.NET シングル ページ アプリケーション (SPA) 詳説
 
ADO.NETとORMとMicro-ORM -dapper dot netを使ってみた
ADO.NETとORMとMicro-ORM -dapper dot netを使ってみたADO.NETとORMとMicro-ORM -dapper dot netを使ってみた
ADO.NETとORMとMicro-ORM -dapper dot netを使ってみた
 
Scala が支える医療系ウェブサービス #jissenscala
Scala が支える医療系ウェブサービス #jissenscalaScala が支える医療系ウェブサービス #jissenscala
Scala が支える医療系ウェブサービス #jissenscala
 
MapR 5.2: MapR コンバージド・コミュニティ・エディションを使いこなす
MapR 5.2: MapR コンバージド・コミュニティ・エディションを使いこなすMapR 5.2: MapR コンバージド・コミュニティ・エディションを使いこなす
MapR 5.2: MapR コンバージド・コミュニティ・エディションを使いこなす
 
PyConAPAC2023 ワークフローエンジン Apache Airflowを用いた 大規模データパイプライン構築と改善
PyConAPAC2023 ワークフローエンジン  Apache Airflowを用いた 大規模データパイプライン構築と改善PyConAPAC2023 ワークフローエンジン  Apache Airflowを用いた 大規模データパイプライン構築と改善
PyConAPAC2023 ワークフローエンジン Apache Airflowを用いた 大規模データパイプライン構築と改善
 
Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方
 
BCPに活かせ!一撃 CloudFormation
BCPに活かせ!一撃 CloudFormationBCPに活かせ!一撃 CloudFormation
BCPに活かせ!一撃 CloudFormation
 
Spring Framework / Boot / Data 徹底活用 〜Spring Data Redis 編〜
Spring Framework / Boot / Data 徹底活用  〜Spring Data Redis 編〜Spring Framework / Boot / Data 徹底活用  〜Spring Data Redis 編〜
Spring Framework / Boot / Data 徹底活用 〜Spring Data Redis 編〜
 
初めてのPadrino
初めてのPadrino初めてのPadrino
初めてのPadrino
 
WordBench京都12月、WordCampUSからのWP REST APIな話
WordBench京都12月、WordCampUSからのWP REST APIな話WordBench京都12月、WordCampUSからのWP REST APIな話
WordBench京都12月、WordCampUSからのWP REST APIな話
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用
 

More from Takeshi Ogawa

今こそ知りたい Spring Data
今こそ知りたい Spring Data今こそ知りたい Spring Data
今こそ知りたい Spring Data
Takeshi Ogawa
 
Spring Cloud Gateway on Kubernetes
Spring Cloud Gateway on KubernetesSpring Cloud Gateway on Kubernetes
Spring Cloud Gateway on Kubernetes
Takeshi Ogawa
 
Spring I/O 2019 Recap - Moduliths
Spring I/O 2019 Recap - ModulithsSpring I/O 2019 Recap - Moduliths
Spring I/O 2019 Recap - Moduliths
Takeshi Ogawa
 
さくっと作るSpring入門 with Google Home
さくっと作るSpring入門 with Google Homeさくっと作るSpring入門 with Google Home
さくっと作るSpring入門 with Google Home
Takeshi Ogawa
 
Spring と TDD
Spring と TDDSpring と TDD
Spring と TDD
Takeshi Ogawa
 
さくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組みさくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組み
Takeshi Ogawa
 

More from Takeshi Ogawa (6)

今こそ知りたい Spring Data
今こそ知りたい Spring Data今こそ知りたい Spring Data
今こそ知りたい Spring Data
 
Spring Cloud Gateway on Kubernetes
Spring Cloud Gateway on KubernetesSpring Cloud Gateway on Kubernetes
Spring Cloud Gateway on Kubernetes
 
Spring I/O 2019 Recap - Moduliths
Spring I/O 2019 Recap - ModulithsSpring I/O 2019 Recap - Moduliths
Spring I/O 2019 Recap - Moduliths
 
さくっと作るSpring入門 with Google Home
さくっと作るSpring入門 with Google Homeさくっと作るSpring入門 with Google Home
さくっと作るSpring入門 with Google Home
 
Spring と TDD
Spring と TDDSpring と TDD
Spring と TDD
 
さくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組みさくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組み
 

Recently uploaded

ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
sugiuralab
 
iMacwoSu_Gong_de_barabaranishitaHua_.pptx
iMacwoSu_Gong_de_barabaranishitaHua_.pptxiMacwoSu_Gong_de_barabaranishitaHua_.pptx
iMacwoSu_Gong_de_barabaranishitaHua_.pptx
kitamisetagayaxxx
 
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
Yuki Miyazaki
 
Microsoft Azureで生成AIを使ってみた話 2024/6/14の勉強会で発表されたものです。
Microsoft Azureで生成AIを使ってみた話 2024/6/14の勉強会で発表されたものです。Microsoft Azureで生成AIを使ってみた話 2024/6/14の勉強会で発表されたものです。
Microsoft Azureで生成AIを使ってみた話 2024/6/14の勉強会で発表されたものです。
iPride Co., Ltd.
 
Humanoid Virtual Athletics Challenge2024 技術講習会 スライド
Humanoid Virtual Athletics Challenge2024 技術講習会 スライドHumanoid Virtual Athletics Challenge2024 技術講習会 スライド
Humanoid Virtual Athletics Challenge2024 技術講習会 スライド
tazaki1
 
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobodyロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
azuma satoshi
 
なぜそのDDDは効果が薄いのか?名ばかりDX案件での経験を踏まえて培った他の思考を交えた現代風?のDDD
なぜそのDDDは効果が薄いのか?名ばかりDX案件での経験を踏まえて培った他の思考を交えた現代風?のDDDなぜそのDDDは効果が薄いのか?名ばかりDX案件での経験を踏まえて培った他の思考を交えた現代風?のDDD
なぜそのDDDは効果が薄いのか?名ばかりDX案件での経験を踏まえて培った他の思考を交えた現代風?のDDD
ssuserfcafd1
 
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
ARISE analytics
 
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMMハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
osamut
 
生成AIの実利用に必要なこと-Practical Requirements for the Deployment of Generative AI
生成AIの実利用に必要なこと-Practical Requirements for the Deployment of Generative AI生成AIの実利用に必要なこと-Practical Requirements for the Deployment of Generative AI
生成AIの実利用に必要なこと-Practical Requirements for the Deployment of Generative AI
Osaka University
 
ろくに電子工作もしたことない人間がIoT用ミドルウェアを作った話(IoTLT vol112 発表資料)
ろくに電子工作もしたことない人間がIoT用ミドルウェアを作った話(IoTLT  vol112 発表資料)ろくに電子工作もしたことない人間がIoT用ミドルウェアを作った話(IoTLT  vol112 発表資料)
ろくに電子工作もしたことない人間がIoT用ミドルウェアを作った話(IoTLT vol112 発表資料)
Takuya Minagawa
 
気ままなLLMをAgents for Amazon Bedrockでちょっとだけ飼いならす
気ままなLLMをAgents for Amazon Bedrockでちょっとだけ飼いならす気ままなLLMをAgents for Amazon Bedrockでちょっとだけ飼いならす
気ままなLLMをAgents for Amazon Bedrockでちょっとだけ飼いならす
Shinichi Hirauchi
 
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
Osaka University
 
20240621_AI事業者ガイドライン_セキュリティパートの紹介_SeiyaShimabukuro
20240621_AI事業者ガイドライン_セキュリティパートの紹介_SeiyaShimabukuro20240621_AI事業者ガイドライン_セキュリティパートの紹介_SeiyaShimabukuro
20240621_AI事業者ガイドライン_セキュリティパートの紹介_SeiyaShimabukuro
Seiya Shimabukuro
 

Recently uploaded (14)

ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
 
iMacwoSu_Gong_de_barabaranishitaHua_.pptx
iMacwoSu_Gong_de_barabaranishitaHua_.pptxiMacwoSu_Gong_de_barabaranishitaHua_.pptx
iMacwoSu_Gong_de_barabaranishitaHua_.pptx
 
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
 
Microsoft Azureで生成AIを使ってみた話 2024/6/14の勉強会で発表されたものです。
Microsoft Azureで生成AIを使ってみた話 2024/6/14の勉強会で発表されたものです。Microsoft Azureで生成AIを使ってみた話 2024/6/14の勉強会で発表されたものです。
Microsoft Azureで生成AIを使ってみた話 2024/6/14の勉強会で発表されたものです。
 
Humanoid Virtual Athletics Challenge2024 技術講習会 スライド
Humanoid Virtual Athletics Challenge2024 技術講習会 スライドHumanoid Virtual Athletics Challenge2024 技術講習会 スライド
Humanoid Virtual Athletics Challenge2024 技術講習会 スライド
 
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobodyロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
 
なぜそのDDDは効果が薄いのか?名ばかりDX案件での経験を踏まえて培った他の思考を交えた現代風?のDDD
なぜそのDDDは効果が薄いのか?名ばかりDX案件での経験を踏まえて培った他の思考を交えた現代風?のDDDなぜそのDDDは効果が薄いのか?名ばかりDX案件での経験を踏まえて培った他の思考を交えた現代風?のDDD
なぜそのDDDは効果が薄いのか?名ばかりDX案件での経験を踏まえて培った他の思考を交えた現代風?のDDD
 
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
 
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMMハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
 
生成AIの実利用に必要なこと-Practical Requirements for the Deployment of Generative AI
生成AIの実利用に必要なこと-Practical Requirements for the Deployment of Generative AI生成AIの実利用に必要なこと-Practical Requirements for the Deployment of Generative AI
生成AIの実利用に必要なこと-Practical Requirements for the Deployment of Generative AI
 
ろくに電子工作もしたことない人間がIoT用ミドルウェアを作った話(IoTLT vol112 発表資料)
ろくに電子工作もしたことない人間がIoT用ミドルウェアを作った話(IoTLT  vol112 発表資料)ろくに電子工作もしたことない人間がIoT用ミドルウェアを作った話(IoTLT  vol112 発表資料)
ろくに電子工作もしたことない人間がIoT用ミドルウェアを作った話(IoTLT vol112 発表資料)
 
気ままなLLMをAgents for Amazon Bedrockでちょっとだけ飼いならす
気ままなLLMをAgents for Amazon Bedrockでちょっとだけ飼いならす気ままなLLMをAgents for Amazon Bedrockでちょっとだけ飼いならす
気ままなLLMをAgents for Amazon Bedrockでちょっとだけ飼いならす
 
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
 
20240621_AI事業者ガイドライン_セキュリティパートの紹介_SeiyaShimabukuro
20240621_AI事業者ガイドライン_セキュリティパートの紹介_SeiyaShimabukuro20240621_AI事業者ガイドライン_セキュリティパートの紹介_SeiyaShimabukuro
20240621_AI事業者ガイドライン_セキュリティパートの紹介_SeiyaShimabukuro
 

Spring data-rest-and-spring-cloud-contract

  • 1. Spring Data REST と Spring Cloud Contract Tagbangers, Inc. #sf_25 #アンケート
  • 2. © Tagbangers, Inc. 1 自己紹介 小川岳史 Spring Lover 10 years 山﨑大 わさもん
  • 3. © Tagbangers, Inc. 2 本日のメニュー • 背景 • Spring Data REST • HATEOAS • Spring Cloud Contract • CDC • Pact
  • 4. © Tagbangers, Inc. 3 背景 • SPA 時代 • よりリッチな UI 表現のために Thymeleaf から Angular などへ • ビジネスロジックの実装が UI 側にも必要なり… Browser Application • ビジネスロジック • CRUD Browser Application • ビジネスロジック • CRUD • ビジネスロジック DB DB
  • 5. © Tagbangers, Inc. 4 工程やチーム構成の変化 BackendFrontend ex. Angular ex. Spring Boot Frontend Team Backend Team User repo repo CI/CDCI/CD code push code push artifactartifact 別々のデプロイ環境 別々のチーム 別々のレポジトリ 別々のリリースサイクル
  • 6. © Tagbangers, Inc. 5 どの URI にアクセスすれば いいの? どんなフォーマットでデー タが取得できるの? 更新できる条件ってなんな の?? そこで発生してきた課題 開発初期段階
  • 7. © Tagbangers, Inc. 6 API の仕様が変更されて UI がバグったんだけど〜 そこで発生してきた課題 リリース後のバージョンアップで
  • 8. © Tagbangers, Inc. 7 解決策 どの URI にアクセスすればいいの? どんなフォーマットでデータが 取得できるの? 更新できる条件ってなんなの?? API の仕様が変更されて UI がバグったんだけど〜 Spring Data REST Spring エコシステムをフル活用! 標準化 + 自動生成 別々に進化できる仕組み Spring Cloud Contract
  • 9. Spring Data REST ✓ 標準化 + 自動生成
  • 10. © Tagbangers, Inc. 9 残念な実装 class ReservationService { Reservation getReservation(long id) { return this.reservationRepository.findById(id); } Reservation createReservation(Reservation reservation) { return this.reservationRepository.save(reservation); } }
  • 11. © Tagbangers, Inc. 10 Spring Data REST とは Entity GET /items GET /items/search GET / items/1 POST /items PUT /items/1 PATCH /items/1 DELETE /items/1 … Item ItemRepository REST スタイルな API エンドポイント URL 設計に迷わない Repository
  • 12. © Tagbangers, Inc. 11 Spring Data REST の始め方 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-rest</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
  • 13. © Tagbangers, Inc. 12 Entity Repository @Entity public class Order { private Long id; private Location location; private LocalDateTime orderedDate; private Status status; } public interface OrderRepository extends PagingAndSortingRepository<Order, Long> { }
  • 14. © Tagbangers, Inc. 13 . ____ _ __ _ _ / / ___'_ __ _ _(_)_ __ __ _ ( ( )___ | '_ | '_| | '_ / _` | / ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |___, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.0.6.RELEASE) ... Mapped "{[/ || ],methods=[HEAD],produces=[application/hal+json || application/json]}" ... Mapped "{[/ || ],methods=[GET],produces=[application/hal+json || application/json]}" ... Mapped "{[/ || ],methods=[OPTIONS],produces=[application/hal+json || application/json]}" ... Mapped "{[/{repository}],methods=[OPTIONS],produces=[application/hal+json || application/json]}" ... Mapped "{[/{repository}],methods=[HEAD],produces=[application/hal+json || application/json]}" ... Mapped "{[/{repository}],methods=[GET],produces=[application/hal+json || application/json]}" ... Mapped "{[/{repository}],methods=[GET],produces=[application/x-spring-data-compact+json || text/uri-list]}" ... Mapped "{[/{repository}],methods=[POST],produces=[application/hal+json || application/json]}" ... Mapped "{[/{repository}/{id}],methods=[OPTIONS],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/{id}],methods=[HEAD],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/{id}],methods=[GET],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/{id}],methods=[PUT],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/{id}],methods=[PATCH],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/{id}],methods=[DELETE],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/{id}/{property}],methods=[GET],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/{id}/{property}/{propertyId}],methods=[GET],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/{id}/{property}],methods=[DELETE],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/{id}/{property}],methods=[GET],produces=[application/x-spring-data-compact+json || text/uri-list]}" Mapped "{[/{repository}/{id}/{property}],methods=[PATCH || PUT || POST],consumes=[application/json || application/x-spring-data-compact+json || text/uri-list], ... Mapped "{[/{repository}/{id}/{property}/{propertyId}],methods=[DELETE],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/search],methods=[OPTIONS],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/search],methods=[HEAD],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/search],methods=[GET],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/search/{search}],methods=[GET],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/search/{search}],methods=[GET],produces=[application/x-spring-data-compact+json]}" Mapped "{[/{repository}/search/{search}],methods=[OPTIONS],produces=[application/hal+json || application/json]}" Mapped "{[/{repository}/search/{search}],methods=[HEAD],produces=[application/hal+json || application/json]}" Mapped "{[/profile],methods=[OPTIONS]}" Mapped "{[/profile],methods=[GET]}" Mapped "{[/profile/{repository}],methods=[GET],produces=[application/alps+json || */*]}" Mapped "{[/profile/{repository}],methods=[OPTIONS],produces=[application/alps+json]}" Mapped "{[/profile/{repository}],methods=[GET],produces=[application/schema+json]}" Mapped "{[/ || ],methods=[GET],produces=[text/html]}" Mapped "{[/browser],methods=[GET]}" 自動的にエンドポイントが登録されている /repository…
  • 15. © Tagbangers, Inc. 14 { "firstName" : "Frodo", "lastName" : "Baggins", "_links" : { "self" : { "href" : "http://localhost:8080/people/1" } } } $ curl http://localhost:8080/people/1 LINK 部 DATA 部
  • 16. © Tagbangers, Inc. 15 HATEOAS • Hypermedia as the Engine of Application State • データ部の他にリンク情報が追加され、関連するリソースをたどることができる • Spring Data REST のリクエスト・レスポンスボディ部のフォーマットは HATEOAS に準拠 • Spring HATEOAS は独立したライブラリでこれだけ使うこともできる
  • 17. © Tagbangers, Inc. 16 フロント側で ID を取り出して個別に URL を組み立てる必要がない ページング情報も $ curl http://localhost:8080/people { "_links" : { "self" : { "href" : "http://localhost:8080/people{?page,size,sort}", "templated" : true }, "search" : { "href" : "http://localhost:8080/people/search" } }, "_embedded" : { "persons" : [ { "firstName" : "Frodo", "lastName" : "Baggins", "_links" : { "self" : { "href" : "http://localhost:8080/people/1" } } } ] }, "page" : { "size" : 20, "totalElements" : 1, "totalPages" : 1, "number" : 0 } } HATEOAS にのっかることでボディ部の フォーマットも悩まない
  • 18. © Tagbangers, Inc. 17 { "description": "iPhone", "status": "IN_PROGRESS", "_links": { "self": { "href": "http://localhost:8080/orders/4" }, "orders": { "href": "http://localhost:8080/orders" }, "cancel": { "href": "http://localhost:8080/orders/4/cancel" }, "complete": { "href": "http://localhost:8080/orders/4/complete" } }
  • 19. if ( order.status == PENDING || order.status == PAID ) { showCancelButton } © Tagbangers, Inc. 18 ビジネスロジックの流出を最小限 に キャンセル判定 ロジック キャンセル判定 ロジック キャンセル判定 ロジック
  • 20. © Tagbangers, Inc. 19 自動生成されて簡単!とはいえ… • とにかく簡単だけど… • Spring Data REST だけでは完成しない • 基本的に CRUD のみ • ビジネスロジックが必要な場合は拡張する Controller Service Repository Database ここは自分で書く Spring Data RESTが よしなに
  • 21. © Tagbangers, Inc. 20 Repository Spring Data REST @RepositoryRest Controller Service @Controller @RestController Endpoint Endpoint Endpoint Domain Model ビジネスロジックの実装パターン EventHandler
  • 22. © Tagbangers, Inc. 21 JSON Schema • JSON Schema から TypeScript のコードの自動生成 TypescriptJson schema 自動生成 curl -H 'Accept:application/schema+json' http://localhost:8080/profile/reservations { "title" : "Reservation", "properties" : { "date" : { "title" : "Date", "readOnly" : false, "type" : "string", "format" : "date-time" }, "name" : { "title" : "Name", "readOnly" : false, "type" : "string" } }, "definitions" : { }, "type" : "object", "$schema" : "http://json-schema.org/draft-04/schema#" } export type Date = string; export type Name = string; export interface Reservation { date?: Date; name?: Name; [k: string]: any; }
  • 23. © Tagbangers, Inc. 22 Admin over Spring Data REST User UI Admin UI Spring Data REST Manual Impl DB
  • 24. © Tagbangers, Inc. 23 全文検索 over Spring Data REST UI Elastic Search Spring Data REST Hibernate Search DB Custom Repository Impl
  • 25. © Tagbangers, Inc. 24 マルチテナント over Spring Data REST UI Spring Data REST Repository DBHibernate Spring Security Authentication Event Listener Filter Tenant
  • 26. © Tagbangers, Inc. 25 ポイント  Spring Data REST を活用してボイラープレートコードを削減する  REST や HATEOAS の流行りの仕様を活用する チーム間のコミュニケーションをフォーマット的なことではなく、 よりビジネス的にフォーカスしたいポイントに絞る!!
  • 27. © Tagbangers, Inc. 26 ポイント BackendFrontend ex. Angular ex. Spring Boot Frontend Team Backend Team User repo repo CI/CDCI/CD code push code push artifactartifact Spring Data REST Spring HATEOAS
  • 28. Spring Cloud Contract でさくっと行う Consumer Driven Contract with Pact 別々に進化できる仕組み
  • 29. © Tagbangers, Inc. 28 工程やチーム構成の変化 BackendFrontend ex. Angular ex. Spring Boot Frontend Team Backend Team User repo repo CI/CDCI/CD code push code push artifactartifact 別々のデプロイ環境 別々のチーム 別々のレポジトリ 別々のリリースサイクル
  • 30. © Tagbangers, Inc. 29 Test Pyramid https://martinfowler.com/bliki/TestPyramid.html
  • 31. © Tagbangers, Inc. 30 モック に置き換える HTTP
  • 32. © Tagbangers, Inc. 31 モック に置き換える その モック 意味がありますか? • インターフェースは正しい?? • 連携するサービスが変更されたら? • だれがメンテナンスするの?
  • 33. © Tagbangers, Inc. 32 Micro service architecture Microservice MicroserviceMicroservice UI Microservice モックモックモックモックモックモックモックモック
  • 34. © Tagbangers, Inc. 33 Spring Cloud Contract Spring Cloud Contract is an umbrella project holding solutions that help users in successfully implementing the Consumer Driven Contracts approach.
  • 35. © Tagbangers, Inc. 34 Pact Pact is a contract testing tool. Contract testing is a way to ensure that services (such as an API provider and a client) can communicate with each other. Without contract testing, the only way to know that services can communicate is by using expensive and brittle integration tests
  • 36. © Tagbangers, Inc. 35 Contract • 契約はインターフェース定義のようなもの • API 仕様書の内容 • Provider が契約を守ることを約束する Contract Consumer Consumer and provider are both agreed with the sentence below.. for example we agreed with on the basis of the Provider’s REST API, that is created hy Provider Test ✔ Test ✔
  • 37. Spring Cloud Contract + Pact で Consumer Driven Contract
  • 38. © Tagbangers, Inc. 37 CDC ステップ 1. テスト書く 2. Contract(Pact file) を自動生成 3. Pact Broker に Pact file を publish Consumer 1. Pact Broker から Contract(Pact file) を取得 2. Test を自動生成(Spring Cloud Contract ) 3. モック を自動生成(Spring Cloud Contract) Provider https://github.com/pact-foundation/pact_broker/wiki/Webhooks
  • 39. © Tagbangers, Inc. 38 1. テストを書く beforeAll ((done) => { provider = new PactWeb({ consumer: ‘sample-client-tenant', provider: ‘sapmle-server-tenant', port: 1234, host: '127.0.0.1' }); }); 前準備 1
  • 40. © Tagbangers, Inc. 39 1. テストを書く beforeAll((done) => { provider.addInteraction({ uponReceiving: 'a request for hello', withRequest: { method: 'GET', path: '/hello' }, willRespondWith: { status: 200, headers: { 'Content-Type': 'application/hal+json;charset=UTF-8' }, body: { reply: 'Hello' } } }).then(done, done.fail); }); 前準備 2
  • 41. © Tagbangers, Inc. 40 1. テストを書く it('should', (done) => { const greetingService: GreetingService = TestBed.get(GreetingTypeService); greetingService.hello().subscribe(response => { expect(response).toEqual({reply: 'Hello'}); done(); }, error => { done.fail(error); }); }); テスト /hello に Get リクエスト
  • 42. © Tagbangers, Inc. 41 CDC ステップ 1. テスト書く 2. Contract(Pact file) を自動生成 3. Pact Broker に Pact file を publish 1. Pact Broker から Contract(Pact file) を取得 2. Test を自動生成(Spring Cloud Contract ) 3. モック を自動生成(Spring Cloud Contract) Consumer Provider
  • 43. © Tagbangers, Inc. 42 2. Pact file ( Contract ) Pact file ... "interactions": [ { "description": "a request for hello", "request": { "method": "GET", "path": "/hello" }, "response": { "status": 200, "headers": { "Content-Type": "application/hal+json;charset=UTF-8" ...
  • 44. © Tagbangers, Inc. 43 CDC ステップ 1. テスト書く 2. Contract(Pact file) を自動生成 3. Pact Broker に Pact file を publish 1. Pact Broker から Contract(Pact file) を取得 2. Test を自動生成(Spring Cloud Contract ) 3. モック を自動生成(Spring Cloud Contract) Contract を共有するためのアプリ https://github.com/pact-foundation/pact_broker/wiki/Webhooks Consumer Provider
  • 45. © Tagbangers, Inc. 44 Pact Broker https://github.com/pact-foundation/pact_broker
  • 46. © Tagbangers, Inc. 45 Pact Broker https://github.com/pact-foundation/pact_broker
  • 47. © Tagbangers, Inc. 46 CDC ステップ 1. テスト書く 2. Contract(Pact file) を自動生成 3. Pact Broker に Pact file を publish 1. Pact Broker から Contract(Pact file) を取得 2. Test を自動生成(Spring Cloud Contract ) 3. モック を自動生成(Spring Cloud Contract) https://github.com/pact-foundation/pact_broker/wiki/Webhooks Consumer Provider
  • 48. © Tagbangers, Inc. 47 CDC ステップ 1. テスト書く 2. Contract(Pact file) を自動生成 3. Pact Broker に Pact file を publish 1. Pact Broker から Contract(Pact file) を取得 2. Test を自動生成(Spring Cloud Contract ) 3. モック を自動生成(Spring Cloud Contract) ビルド時にテストを生成 + テスト実行 https://github.com/pact-foundation/pact_broker/wiki/Webhooks Consumer Provider
  • 49. © Tagbangers, Inc. 48 CDC ステップ 1. テスト書く 2. Contract(Pact file) を自動生成 3. Pact Broker に Pact file を publish 1. Pact Broker から Contract(Pact file) を取得 2. Test を自動生成(Spring Cloud Contract ) 3. モック を自動生成(Spring Cloud Contract) https://github.com/pact-foundation/pact_broker/wiki/Webhooks Consumer Provider
  • 50. © Tagbangers, Inc. 49 CDC ステップ 1. テスト書く 2. Contract(Pact file) を自動生成 3. Pact Broker に Pact file を publish 1. Pact Broker から Contract(Pact file) を取得 2. Test を自動生成(Spring Cloud Contract ) 3. モック を自動生成(Spring Cloud Contract) 成果物としてWireMockの定義ファイルができる https://github.com/pact-foundation/pact_broker/wiki/Webhooks Consumer Provider
  • 51. © Tagbangers, Inc. 50 APIが実装されたか知りたい https://github.com/pact-foundation/pact_broker/wiki/Webhooks Broker のステータス確認で対応状況を把握
  • 52. © Tagbangers, Inc. 51 Pact Broker https://github.com/pact-foundation/pact_broker
  • 53. © Tagbangers, Inc. 52 破壊的な API の実装の変更 https://github.com/pact-foundation/pact_broker/wiki/Webhooks テストが通らないので破壊的な変更だとわかる!
  • 54. © Tagbangers, Inc. 53 使用されている API がわかる! https://github.com/pact-foundation/pact_broker
  • 56. © Tagbangers, Inc. 55 まとめ BackendFrontend ex. Angular ex. Spring Boot Frontend Team Backend Team User repo repo CI/CDCI/CD code push code push artifactartifact Spring Data REST Spring HATEOAS Spring Cloud Contract

Editor's Notes

  1. スタンダードな API 設計で・・・ Affordance
  2. Spring Data REST の話に戻して Spring Data REST のマッピングの優先順位は最低
  3. ビジネスロジックがフロントエンド側にも必要になり、モデルオブジェクトなど冗長なコードが発生していないでしょうか Spring Data REST はエンティティの情報から自動的に JSON Schema を作る機能もあります。 この JSON Schema の情報を使って例えば Angular でしたら Typescript の型をコード生成することも可能です。
  4. Spring Cloud Contract Consumer Driven Contract Contract Testing
  5. チームを分割したことにより ・ お互いのチームの開発進捗に関係なく開発を進めたい ・ 独自に進化していきたい 変更を加えても壊れないシステムにしたいですよね。 壊れてしまうのであればデプロイ前に知ることができると安心して開発を進めることが出来ます。 アプリケーションをバージョンアップし、自身をもってデプロイしたい
  6. テストの自動化にも課題はたくさんあります。 テストピラミッドが表すように、e2e、integration test と呼ばれるようなテストは ・コストがかかる ・時間がかかる →エラーの検知に時間がかかる ・環境構築が複雑 → 環境起因のエラーに悩まされる せっかくチームを分割して専門性を高め、独自に進化していきたいのにテストに足を引っ張られてしまっては意味がありません。 e2e、 integration test を代替する方法を考えなければいけません。 もっとも簡単な方法は integration する相手を モック に置き換えてしまうことです。 モック、スタブ、テストダブルなど言葉はいろいろとありますが、今日はモックという言葉で統一させてもらう
  7. モック に置き換えると ・テストのための環境構築がらく ・速い というメリットがありますが
  8. モック に置き換えると ・テストのための環境構築がらく ・速い というメリットがありますが インターフェースは正しい?? 連携するサービスが変更されたら? だれがメンテナンスするの? メリットも大きいですが、さらなる問題点が出てきてしまいます。 意味のある モック を維持するのはとても大変です
  9. UI と API を分けただけなのに、はやりの Architecture はもっと大変なは・・・・
  10. ありますよ。 Spring Cloud Contract。 Spring Cloud とついているので一見 UI + API くらいの分割では意味のないものに思えますが、 ちゃんと使えます。 Consumer Driven Contract の実装を手助け Spring Cloud Contract はとても雑にいうと 意味のある モック を簡単に準備する便利ツールです
  11. ありますよ。 Spring Cloud Contract。 Spring Cloud とついているので一見 UI + API くらいの分割では意味のないものに思えますが、 ちゃんと使えます。 Spring Cloud Contract はとても雑にいうと 意味のある モック を簡単に準備する便利ツールです
  12. 契約というのは現実世界の契約とそれほど違いはなくて、 例えば携帯電話の契約みたいなもんです。 契約書の内容を確認して問題なければ、サインしますよね。 サインしたら契約完了で、端末だったり通信サービスを受けることが出来ます。 Spring Cloud Contract、 CDC の Contract も同じようなもので 契約の内容をそれぞれのアプリケーションが確認して、間違いなければサインする すると、mock や e2e を補完してくれような恩恵を受けることができるということです。
  13. ここからは Consumer と Provider という言葉を使います
  14. 期待するレスポンス
  15. 期待するレスポンス
  16. 期待するレスポンス
  17. Pact ファイル と呼ばれる Contract を共有するための web application Docker などで自分で用意することもできるし Hostされているフリーの Broker service もあるよ 自前で準備するのも面倒なのであるプロジェクトではフリーの Broker を使ったりもしています
  18. 今回の例は 1 対 1 の 連携ですが Micro service のように多数のサービスが存在するばいいに便利な Service の連携を可視化する機能もあります HAL Browser もあるよ API ドキュメントも参照できる かなり便利なアプリケーション
  19. Consumer 側では テストを検証することで アプリケーションが実際にAPIを使用していることを Provider 側では 自動生成Contract が守られる
  20. モックを自動生成とかいておりますが、実際には Spring Cloud Contract が対応している WireMock という モックサーバー の定義ファイルが出来ます。 WireMock は 定義ファイルを元に動作するモックサーバーです
  21. Pact ファイルを共有するための web application Docker などで自分で用意することもできるし HostされているフリーのBroker もあるよ
  22. Pact ファイルを共有するための web application Docker などで自分で用意することもできるし HostされているフリーのBroker もあるよ
  23. Spring Data REST でをフル活用することで「いつもの」(単純なCRUDとか)作業は自動生成! HATEOAS を採用してらくに設計をしよう! → フォーカスしたいポイントに集中しよう! コストの高い Integration Test を CDC に置き換えて有効なテストを! →別々に進化できる仕組み