SlideShare a Scribd company logo
1 of 201
Download to read offline
REST with Spring Boot
槙 俊明(@making)
JavaQne 2015 #jqfk
2015-01-24
自己紹介
• @making
• http://blog.ik.am
• 公私ともにSpringヘビーユーザー
• 日本Javaユーザーグループ幹事
祝「はじめてのSpring Boot」出版
http://bit.ly/hajiboot
最近、第2版
が出ました!
今日のお話
• Spring Boot概要
• RESTについて色々
• Richardson Maturity Model
• Spring HATEOAS / Spring Data REST
• JSON Patch
• Spring Sync
• Securing REST Serivces
• Spring Security OAuth / Spring Session
Spring Bootの概要
Spring Boot概要
• Springを使って簡単にモダンな
アプリケーションを開発するた
めの仕組み
• AutoConfigure + 組み込みサー
バーが特徴
<parent>	
<groupId>org.springframework.boot</groupId>	
<artifactId>spring-boot-starter-parent</artifactId>	
<version>1.2.1.RELEASE</version>	
</parent>	
<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>	
</dependency>	
</dependencies>	
<build>	
<plugins>	
<plugin>	
<groupId>org.springframework.boot</groupId>	
<artifactId>spring-boot-maven-plugin</artifactId>	
</plugin>	
</plugins>	
</build>	
<properties>	
<java.version>1.8</java.version>	
</properties>	
 
この設定を追加
するだけ
package com.example;	
!
import org.springframework.boot.SpringApplication;	
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;	
import org.springframework.web.bind.annotation.RequestMapping;	
import org.springframework.web.bind.annotation.RestController;	
!
@RestController	
@EnableAutoConfiguration	
public class App {	
!
@RequestMapping("/")	
String home() {	
return "Hello World!";	
}	
!
public static void main(String[] args) {	
SpringApplication.run(App.class, args);	
}	
}
魔法のアノテーション
mainメソッドでアプリ実行
ログ
組込Tomcatが起動した
ログ
組込Tomcatが起動した
実行可能jarを作成
$ mvn package
jarを実行
$ java -jar target/jggug-helloworld-1.0.0-
SNAPSHOT.jar
プロパティを変更して実行
$ java -jar target/jggug-helloworld-1.0.0-
SNAPSHOT.jar --server.port=8888
--(プロパティ名)=(プロパティ値)
@SpringBootApplication	
@RestController	
public class App {	
!
@RequestMapping("/")	
String home() {	
return "Hello World!";	
}	
!
public static void main(String[] args) {	
SpringApplication.run(App.class, args);	
}	
}
Spring Boot 1.2より
@SpringBootApplication	
@RestController	
public class App {	
!
@RequestMapping("/")	
String home() {	
return "Hello World!";	
}	
!
public static void main(String[] args) {	
SpringApplication.run(App.class, args);	
}	
}
Spring Boot 1.2より
@EnableAutoConfiguration	
+ @Configuration	
+ @ComponentScan
RESTについて
REST?
• クライアントとサーバ間でデータをやりと
りするためのソフトウェアアーキテクチャ
スタイルの一つ
• サーバーサイドで管理している情報の中か
らクライアントに提供すべき情報を「リソー
ス」として抽出し、リソースをHTTPで操作
RESTに関するいろいろな話題
• Richardson Maturity Model
• JSON Patch
• Security
Richardson Maturity Model
Richardson Maturity Model
http://martinfowler.com/articles/richardsonMaturityModel.html
RESTの成熟モデル
Richardson Maturity Model
http://martinfowler.com/articles/richardsonMaturityModel.html
RESTの成熟モデル
あなたの
Level 0: Swamp of POX
• POX (Plain Old XML)
• SOAP、XML-RPC
転送プロトコルとして
HTTPを使っているだけ。
通常POSTオンリー
Level 0: Swamp of POX
Level 1: Resources
• /customers、/usersなど
• なんちゃってREST
URLに名詞を使う。
Level 1: Resources
Level 2: HTTP Vebs
• GET/POST/PUT/DELETEなど
• 一般的にみんなが言っている”REST”
HTTPメソッドを動詞に使う。
ヘッダやステータスを活用
Level 2: HTTP Vebs
ここまでは対応している
Webフレームワークは多い
Spring Boot + Spring MVC
@SpringBootApplication	
@RestController @RequestMapping("user")	
public class App {	
public static void main(String[] args) {	
SpringApplication.run(App.class, args);	
}	
@RequestMapping(method = RequestMethod.GET)	
User get() {	
return new User("demo", "password");	
}	
@RequestMapping(method = RequestMethod.POST)

ResponseEntity<User> post(@RequestBody User user) {

// create

return ResponseEntity	
.created(location).body(created);

}	
}
Level 3: Hypermedia
Controls
• HATEOAS (Hypermedia As The
Engine Of Application State)
Hypermediaリンクを
使用してナビゲーション。
ユーザーにサービス全体の
知識を強いない。
Level 3: Hypermedia
Controls
Level 3: Hypermedia
Controls
{	
"name": "Alice",	
"links": [ {	
"rel": "self",	
"href": "http://.../customer/1"	
} ]	
}
Level 3: Hypermedia
Controls
{	
"name": "Alice",	
"links": [ {	
"rel": "self",	
"href": "http://.../customer/1"	
}, {	
"rel": "user",	
"href": "http://.../customer/1/user"	
} ]	
}
Level 3: Hypermedia
Controls
{	
"name": "Alice",	
"links": [ {	
"rel": "self",	
"href": "http://.../customer/1"	
}, {	
"rel": "user",	
"href": "http://.../customer/1/user"	
} ]	
}
関連するリソースの
リンクが含まれる
Spring HATEOAS
Spring MVCにHATEOASの概念を追加
• リソースのモデルにLink追加
• HAL等のデータフォーマットに対応
具体例で説明
扱うモデル
Bookmarkエンティティ
@Entity	
public class Bookmark {	
@ManyToOne @JsonIgnore	
Account account;	
@Id @GeneratedValue	
Long id;	
String uri;	
String description;	
// omitted	
}
Accountエンティティ
@Entity	
public class Account {	
@OneToMany(mappedBy = "account")	
Set<Bookmark> bookmarks;	
@Id @GeneratedValue	
Long id;	
@JsonIgnore	
String password;	
String username;	
// omitted	
}
BookmarkRepository
public interface BookmarkRepository	
extends JpaRepository<Bookmark, Long> {	
!
Collection<Bookmark> 	
findByAccountUsername(String username);	
!
}
BookmarkRepository
public interface BookmarkRepository	
extends JpaRepository<Bookmark, Long> {	
!
Collection<Bookmark> 	
findByAccountUsername(String username);	
!
}
Spring Data JPAを使用。
CRUDを簡単に使える。
BookmarkRepository
public interface BookmarkRepository	
extends JpaRepository<Bookmark, Long> {	
!
Collection<Bookmark> 	
findByAccountUsername(String username);	
!
}
Spring Data JPAを使用。
CRUDを簡単に使える。
命名規約に対応したクエリが
実行されるメソッド(実装不要)
BookmarkRepository
public interface BookmarkRepository	
extends JpaRepository<Bookmark, Long> {	
!
Collection<Bookmark> 	
findByAccountUsername(String username);	
!
}
Spring Data JPAを使用。
CRUDを簡単に使える。
命名規約に対応したクエリが
実行されるメソッド(実装不要)
SELECT b
FROM Bookmark b
WHERE
b.account.username= :username
AccountRepository
public interface AccountRepository 	
extends JpaRepository<Account, Long> {	
!
Optional<Account> 	
findByUsername(String username);	
!
}
AccountRepository
public interface AccountRepository 	
extends JpaRepository<Account, Long> {	
!
Optional<Account> 	
findByUsername(String username);	
!
}
Java SE 8のOptionalに対応。
1件取得結果の存在有無をOptionalで表現
Level 2
普通のSpring MVCプログラミング
Controller
@RestController @RequestMapping("/{userId}/bookmarks")	
class BookmarkRestController {	
@Autowired BookmarkRepository bookmarkRepository;	
@Autowired AccountRepository accountRepository;	
@RequestMapping(value = "/{bookmarkId}", 	
method = RequestMethod.GET)

Bookmark readBookmark(	
@PathVariable String userId,	
@PathVariable Long bookmarkId) {

this.validateUser(userId);

return this.bookmarkRepository.findOne(bookmarkId);

}	
// …	
}
Controller
@RequestMapping(method = RequestMethod.POST)	
ResponseEntity<?> add(@PathVariable String userId, 	
@RequestBody Bookmark in) {	
return this.accountRepository	
.findByUsername(userId)	
.map(account -> {	
Bookmark result = bookmarkRepository.save(	
new Bookmark(account, in.uri, 	
in.description));	
URI location = …;	
return ResponseEntity	
.created(location).body(result);	
})	
.orElseThrow(() -> 	
new UserNotFoundException(userId));	
}
起動
@SpringBootApplication

public class Application {

@Bean

CommandLineRunner init(AccountRepository accountRepository,

BookmarkRepository bookmarkRepository) {

return (evt) -> Stream.of("kis", "skrb", "making")

.forEach(a -> {

Account account = accountRepository.save(new Account(a,

"password"));

bookmarkRepository.save(new Bookmark(account,

"http://bookmark.com/1/" + a, 	
"A description"));

bookmarkRepository.save(new Bookmark(account,

"http://bookmark.com/2/" + a, 	
"A description"));});

}

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}
起動
@SpringBootApplication

public class Application {

@Bean

CommandLineRunner init(AccountRepository accountRepository,

BookmarkRepository bookmarkRepository) {

return (evt) -> Stream.of("kis", "skrb", "making")

.forEach(a -> {

Account account = accountRepository.save(new Account(a,

"password"));

bookmarkRepository.save(new Bookmark(account,

"http://bookmark.com/1/" + a, 	
"A description"));

bookmarkRepository.save(new Bookmark(account,

"http://bookmark.com/2/" + a, 	
"A description"));});

}

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}
起動時に実行されるクラス
Example: GET
$ curl -X GET localhost:8080/making/bookmarks	
[{	
"description": "A description",	
"uri": "http://bookmark.com/1/making",	
"id": 5	
},	
{	
"description": "A description",	
"uri": "http://bookmark.com/2/making",	
"id": 6	
}]
Example: GET
$ curl -X GET localhost:8080/making/bookmarks/5	
{	
"description": "A description",	
"uri": "http://bookmark.com/1/making",	
"id": 5	
}
Example: POST
$ curl -v -X POST localhost:8080/making/
bookmarks -H 'Content-Type: application/json' -d
'{"url":"http://bit.ly/hajiboot", "description":"
はじめてのSpring Boot"}'	
(略)	
< HTTP/1.1 201 Created	
< Location: http://localhost:8080/making/
bookmarks/7	
(略)	
{"id":7,"uri":null,"description":"はじめての
Spring Boot"}
Error Handling
@ResponseStatus(HttpStatus.NOT_FOUND)	
class UserNotFoundException	
extends RuntimeException {	
public UserNotFoundException(String userId) {	
super("could not find user '" 	
+ userId + "'.");	
}	
}
Error Handling
$ curl -v -X GET localhost:8080/maki/bookmarks/6	
(略)	
< HTTP/1.1 404 Not Found	
(略)	
{	
"path": "/maki/bookmarks/6",	
"message": "could not find user 'maki'.",	
"exception": "bookmarks.UserNotFoundException",	
"error": "Not Found",	
"status": 404,	
"timestamp": 1421044115740	
}
Level 3
<dependency>	
<groupId>org.springframework.hateoas</groupId>	
<artifactId>spring-hateoas</artifactId>	
</dependency>
Spring HATEOASを使用
Level 3
<dependency>	
<groupId>org.springframework.hateoas</groupId>	
<artifactId>spring-hateoas</artifactId>	
</dependency>
Spring HATEOASを使用
Spring Bootを使うと依存関係を定義す
るだけでHATEOASを使える
class BookmarkResource extends ResourceSupport {

private final Bookmark bookmark;

public BookmarkResource(Bookmark bookmark) {

String username = bookmark.getAccount().getUsername();

this.bookmark = bookmark;

this.add(new Link(bookmark.getUri(), "bookmark-uri"));

this.add(linkTo(BookmarkRestController.class, username)

.withRel("bookmarks"));

this.add(linkTo(methodOn(BookmarkRestController.class, 	
username)

.readBookmark(username, 	
bookmark.getId()))

.withSelfRel());

}

public Bookmark getBookmark() {/**/}

}
class BookmarkResource extends ResourceSupport {

private final Bookmark bookmark;

public BookmarkResource(Bookmark bookmark) {

String username = bookmark.getAccount().getUsername();

this.bookmark = bookmark;

this.add(new Link(bookmark.getUri(), "bookmark-uri"));

this.add(linkTo(BookmarkRestController.class, username)

.withRel("bookmarks"));

this.add(linkTo(methodOn(BookmarkRestController.class, 	
username)

.readBookmark(username, 	
bookmark.getId()))

.withSelfRel());

}

public Bookmark getBookmark() {/**/}

}
HypermediaLinkを表
現するための基本的な
情報を持つ
class BookmarkResource extends ResourceSupport {

private final Bookmark bookmark;

public BookmarkResource(Bookmark bookmark) {

String username = bookmark.getAccount().getUsername();

this.bookmark = bookmark;

this.add(new Link(bookmark.getUri(), "bookmark-uri"));

this.add(linkTo(BookmarkRestController.class, username)

.withRel("bookmarks"));

this.add(linkTo(methodOn(BookmarkRestController.class, 	
username)

.readBookmark(username, 	
bookmark.getId()))

.withSelfRel());

}

public Bookmark getBookmark() {/**/}

}
HypermediaLinkを表
現するための基本的な
情報を持つ
ControllerLinkBuilder
class BookmarkResource extends ResourceSupport {

private final Bookmark bookmark;

public BookmarkResource(Bookmark bookmark) {

String username = bookmark.getAccount().getUsername();

this.bookmark = bookmark;

this.add(new Link(bookmark.getUri(), "bookmark-uri"));

this.add(linkTo(BookmarkRestController.class, username)

.withRel("bookmarks"));

this.add(linkTo(methodOn(BookmarkRestController.class, 	
username)

.readBookmark(username, 	
bookmark.getId()))

.withSelfRel());

}

public Bookmark getBookmark() {/**/}

}
“bookmark-uri"というrelで
対象のブックマークへのlinkを追加
class BookmarkResource extends ResourceSupport {

private final Bookmark bookmark;

public BookmarkResource(Bookmark bookmark) {

String username = bookmark.getAccount().getUsername();

this.bookmark = bookmark;

this.add(new Link(bookmark.getUri(), "bookmark-uri"));

this.add(linkTo(BookmarkRestController.class, username)

.withRel("bookmarks"));

this.add(linkTo(methodOn(BookmarkRestController.class, 	
username)

.readBookmark(username, 	
bookmark.getId()))

.withSelfRel());

}

public Bookmark getBookmark() {/**/}

}
"bookmarks"というrelで
ブックマークコレクションの
リソースへのlinkを追加
class BookmarkResource extends ResourceSupport {

private final Bookmark bookmark;

public BookmarkResource(Bookmark bookmark) {

String username = bookmark.getAccount().getUsername();

this.bookmark = bookmark;

this.add(new Link(bookmark.getUri(), "bookmark-uri"));

this.add(linkTo(BookmarkRestController.class, username)

.withRel("bookmarks"));

this.add(linkTo(methodOn(BookmarkRestController.class, 	
username)

.readBookmark(username, 	
bookmark.getId()))

.withSelfRel());

}

public Bookmark getBookmark() {/**/}

}
"self"というrelで
自身へのlinkを追加
@RequestMapping(value = “/{bookmarkId}",	
method = RequestMethod.GET)	
BookmarkResource readBookmark(	
@PathVariable String userId, 	
@PathVariable Long bookmarkId) {	
this.validateUser(userId);	
return new BookmarkResource(	
this.bookmarkRepository	
.findOne(bookmarkId));	
}
@RequestMapping(method = RequestMethod.POST)

ResponseEntity<?> add(@PathVariable String userId,
@RequestBody Bookmark in) {

return accountRepository.findByUsername(userId)

.map(account -> {

Bookmark bookmark = bookmarkRepository

.save(new Bookmark(account, in.uri, 	
in.description));

Link selfLink = new BookmarkResource(bookmark)	
.getLink("self");

URI location = URI.create(selfLink.getHref());

return ResponseEntity	
.created(location).body(bookmark);
})

.orElseThrow(() -> 	
new UserNotFoundException(userId));

}
サンプル: GET
$ curl -X GET localhost:8080/making/bookmarks/5	
{	
"_links": {	
"self": {	
"href": "http://localhost:8080/making/bookmarks/5"	
},	
"bookmarks": {	
"href": "http://localhost:8080/making/bookmarks"	
},	
"bookmark-uri": {	
"href": "http://bookmark.com/1/making"	
}	
},	
"bookmark": {	
"description": "A description",	
"uri": "http://bookmark.com/1/making",	
"id": 5	
}	
}
Example: GET
$ curl -v -X GET localhost:8080/making/bookmarks/6	
> GET /making/bookmarks/6 HTTP/1.1	
> User-Agent: curl/7.30.0	
> Host: localhost:8080	
> Accept: */*	
>	
< HTTP/1.1 200 OK	
< Server: Apache-Coyote/1.1	
< Content-Type: application/hal+json;charset=UTF-8	
< Transfer-Encoding: chunked	
< Date: Mon, 12 Jan 2015 05:45:40 GMT	
<	
(略)
HALという規格の
フォーマットを使用
している
HAL
http://stateless.co/hal_specification.html
Hypertext Application Language
Hypermediaを表現する
フォーマット仕様の1つ
@ControllerAdvice	
class BookmarkControllerAdvice {	
!
@ResponseBody	
@ExceptionHandler(UserNotFoundException.class)	
@ResponseStatus(HttpStatus.NOT_FOUND)	
VndErrors userNotFoundExceptionHandler(	
UserNotFoundException ex) {	
return new VndErrors("error", ex.getMessage());	
}	
}	
Error Handling
$ curl -X GET localhost:8080/maki/bookmarks/5	
[	
{	
"message": "could not find user 'maki'.",	
"logref": "error"	
}	
] Vnd.Errror規格の
エラーフォーマット
Error Handling
https://github.com/blongden/vnd.error
普通の人はLevel 2で十分。
こだわりたい人はLevel 3へ。
Spring Data REST
Spring Dataのリポジトリを
そのままREST APIとしてExport
SpringData
SpringData
JPA
SpringData
MongoDB
SpringData
Xxx
JPA
SpringDataREST
RDB
JSON
MongoDB
Xxx
Spring Bootから使う場合
<dependency>	
<groupId>org.springframework.boot</groupId>	
<artifactId>spring-boot-starter-data-rest</artifactId>	
</dependency>
Spring Bootを使うと依存関係を定義す
るだけでSpring Data RESTを使える
ALPS
Application-Level Profile Semantics
http://alps.io/
Event Handler
@RepositoryEventHandler(Bookmark.class)	
public class BookmarkEventHandler {	
@HandleBeforeSave 	
public void beforeSave(Bookmark p) {	
/* … */	
}	
@HandleAfterDelete 	
public void afterDelete(Bookmark p) {	
/* … */	
}	
}
超短期間でRESTサービスをつくる
必要がある場合に強力
JSON Patch
コレクションの変更
[{"value":"a"},{"value":"b"},{"value":"c"}]
[{"value":"a"},{"value":"c"},{"value":"d"}]
Original
Modified
[+] {"value":"d"} を4番目に追加
[-] 2番目の要素を削除
…
コレクションの変更
[{"value":"a"},{"value":"b"},{"value":"c"}]
[{"value":"a"},{"value":"c"},{"value":"d"}]
Original
Modified
[+] {"value":"d"} を4番目に追加
[-] 2番目の要素を削除
…
もっと効率的なデータ転送を!
動機
より効率的なデータ転送
複数のクライアント間での
データ同期
オフライン作業の反映
http://www.slideshare.net/briancavalier/differential-sync-and-json-patch-s2-gx-2014/13
http://www.slideshare.net/briancavalier/differential-sync-and-json-patch-s2-gx-2014/13
Diff & Patch!
JSON Patch
RFC 6902
パッチをJSONで表現
PATCHメソッドで送信
JSON Pointer (RFC 6901)で指定し
たJSONパスへの操作を表現
application/json-patch+json
JSON Patch
RFC 6902
パッチをJSONで表現
PATCHメソッドで送信
JSON Pointer (RFC 6901)で指定し
たJSONパスへの操作を表現
application/json-patch+json
patch(diff(a, b), a) === b
を満たすこと
JSON Patch
[{"value":"a"},{"value":"b"},{"value":"c"}]
[	
{"op":"add","path":"/3","value":{"value":"d"}},	
{"op":"remove","path":"/1"}	
]
[{"value":"a"},{"value":"c"},{"value":"d"}]
Original
Modified
Patch
典型的なREST
POST /todos {"title":"fizzbuz","done":false }
PUT /todos/1 {"title":"fizzbuz","done":true }
PATCH /todos/2 {"done":true }
DELETE /todos/3
典型的なREST
POST /todos {"title":"fizzbuz","done":false }
PUT /todos/1 {"title":"fizzbuz","done":true }
PATCH /todos/2 {"done":true }
DELETE /todos/3HTTP通信回数=操作回数
リソースが増えるとさらに増える
PATCH /todos [	
{"op":"add","path":"-","value":	
{"title":"fizzbuzz","done":false}},	
{"op":"replace","path":"/1","value":	
{"title":"fizzbuzz","done":true}},	
{"op":"replace","path":"/2/done",	
"value":true},	
{"op":"remove","path":"/3"}	
]
JSON PatchがあるREST
PATCH /todos [	
{"op":"add","path":"-","value":	
{"title":"fizzbuzz","done":false}},	
{"op":"replace","path":"/1","value":	
{"title":"fizzbuzz","done":true}},	
{"op":"replace","path":"/2/done",	
"value":true},	
{"op":"remove","path":"/3"}	
]
JSON PatchがあるREST
HTTP通信回数が1回
リソースが増えても1回
操作もアトミック
Spring Sync
* https://github.com/spring-projects/spring-sync
* https://github.com/spring-projects/spring-sync-samples
* https://spring.io/blog/2014/10/22/introducing-spring-sync
@Configuration	
@EnableDifferentialSynchronization	
public class DiffSyncConfig extends DiffSyncConfigurerAdapter {	
@Autowired	
private PagingAndSortingRepository<Todo, Long> repo;	 	
@Override	
public void addPersistenceCallbacks(PersistenceCallbackRegistry registry)
{	
registry.addPersistenceCallback(	
new JpaPersistenceCallback<Todo>(repo, Todo.class));	
}	
}
Spring (MVC)でJSON Patchを扱うためのプロジェクト
まだ1.0.0.RC1
乞うご期待
Securing REST Services
どっちが好き?
• HttpSessionを使わない
• HttpSessionを使う
どっちが好き?
• HttpSessionを使わない
• HttpSessionを使う
KVSにデータを保存
OAuth 2.0を利用
OAuth 2.0
• アクセストークンを使って認可する
標準的な仕組み
• 多くのAPIプロバイダがOAuthによ
るリソースアクセスを提供
OAuth2.0の基本
Resource
Owner
Client
Resource
Server
Authorization
Server
OAuth2.0の基本
Resource
Owner
Client
Resource
Server
Authorization
Server
Github APIの例
OAuth2.0の基本
Resource
Owner
Client
Resource
Server
Authorization
Server
Githubの
アカウント管理
Github API
Github API
を使ったサービス
プロバイダ(アプリ)
エンドユーザー
(Githubユーザー)
OAuth2.0の流れ
Resource
Owner
Client
Resource
Server
Authorization
Server
OAuth2.0の流れ
Resource
Owner
Client
Resource
Server
Authorization
Server
サービスへ
リクエスト
OAuth2.0の流れ
Resource
Owner
Client
Resource
Server
Authorization
Server
何か
サービスへ
リクエスト
OAuth2.0の流れ
Resource
Owner
Client
Resource
Server
Authorization
Server
何か
アクセストークン
サービスへ
リクエスト
OAuth2.0の流れ
Resource
Owner
Client
Resource
Server
Authorization
Server
何か
アクセストークン
アクセストークン
サービスへ
リクエスト
OAuth2.0の流れ
Resource
Owner
Client
Resource
Server
Authorization
Server
何か
アクセストークン
アクセストークン
リソース
サービスへ
リクエスト
OAuth2.0の流れ
Resource
Owner
Client
Resource
Server
Authorization
Server
何か
アクセストークン
アクセストークン
リソース
サービスへ
リクエスト
サービスからの
レスポンス
OAuth2.0の流れ
Resource
Owner
Client
Resource
Server
Authorization
Server
何か
アクセストークン
アクセストークン
リソース
サービスへ
リクエスト
サービスからの
レスポンス
ここの方式
(どうやってアクセストークンを交換するか)
=GrantType
Grant Types
• Authorization Code
• Resource Owner Password Credentials
• Client Credentials
• Refresh Token
• Implicit
• JWT Bearer
Grant Types
• Authorization Code
• Resource Owner Password Credentials
• Client Credentials
• Refresh Token
• Implicit
• JWT Bearer
Authorization Code
(grant_type=authorization_code)
• 認可コードとアクセストークンを交換
• 一般的にOAuthと思われているやつ
画像: http://www.binarytides.com/php-add-login-with-github-to-your-website/
Resource
Owner
Client
Resource
Server
Authorization
Server
Resource
Owner
Client
Resource
Server
Authorization
Server
サービスへ
リクエスト
Resource
Owner
Client
Resource
Server
Authorization
Server
Login Page
サービスへ
リクエスト
Resource
Owner
Client
Resource
Server
Authorization
Server
Login Page
サービスへ
リクエスト
Resource
Owner
Client
Resource
Server
Authorization
Server
Login Pageログイン
サービスへ
リクエスト
Resource
Owner
Client
Resource
Server
Authorization
Server
Login Pageログイン
サービスへ
リクエスト
Resource
Owner
Client
Resource
Server
Authorization
Server
Login Page
認可コード
ログイン
サービスへ
リクエスト
Resource
Owner
Client
Resource
Server
Authorization
Server
Login Page
認可コード
ログイン
サービスへ
リクエスト
Resource
Owner
Client
Resource
Server
Authorization
Server
Login Page
認可コード
認可コード
ログイン
サービスへ
リクエスト
Resource
Owner
Client
Resource
Server
Authorization
Server
Login Page
認可コード
認可コード
認可コード
ログイン
サービスへ
リクエスト
Resource
Owner
Client
Resource
Server
Authorization
Server
Login Page
認可コード
認可コード
アクセストークン
認可コード
ログイン
サービスへ
リクエスト
http://brentertainment.com/oauth2/
GET /authorize?
response_type=code&client_id=s6BhdRkqt3&
state=xyz&redirect_uri=https%3A%2F
%2Fclient%2Eexample%2Ecom%2Fcb
GET /authorize?
response_type=code&client_id=s6BhdRkqt3&
state=xyz&redirect_uri=https%3A%2F
%2Fclient%2Eexample%2Ecom%2Fcb
302 Found	
Location: https://client.example.com/cb?
code=0fcfa4625502c209702e6d12fc67f4c298e
44373&state=xyz
認可コード取得
認可コード取得POST /token	
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW	
grant_type=authorization_code&code=0fcfa4625502c20
9702e6d12fc67f4c298e44373&redirect_uri=https%3A%2F
%2Fclient%2Eexample%2Ecom%2Fcb
client_id:client_secret	
をBase64エンコード
認可コード取得POST /token	
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW	
grant_type=authorization_code&code=0fcfa4625502c20
9702e6d12fc67f4c298e44373&redirect_uri=https%3A%2F
%2Fclient%2Eexample%2Ecom%2Fcb
client_id:client_secret	
をBase64エンコード
200 OK	
!
{"access_token":"e651bdf91e704c0f3d060ffd
4ff0403eb087f519","expires_in":
3600,"token_type":"bearer"}
アクセストークン取得
アクセストークン取得
GET /api/friends	
Authorization: Bear e651bdf91e704c0f3d060ffd4ff0403eb087f519
リソース取得
Resource Owner Password Credentials
(grant_type=password)
• ユーザー名・パスワードとアクセストー
クンを交換
• Clientが直接ユーザー名・パスワード
を知ることになるので、通常公式アプ
リで使用される。
Resource
Owner
Client
Resource
Server
Authorization
Server
Authorization Server
と提供元が同じ
Resource
Owner
Client
Resource
Server
Authorization
Server
ユーザー名・
パスワード
Authorization Server
と提供元が同じ
Resource
Owner
Client
Resource
Server
Authorization
Server
ユーザー名・
パスワード
アクセストークン
Authorization Server
と提供元が同じ
POST /token	
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW	
!
grant_type=password&username=demouser&password=tes
tpass
client_id:client_secret	
をBase64エンコード
POST /token	
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW	
!
grant_type=password&username=demouser&password=tes
tpass
client_id:client_secret	
をBase64エンコード
200 OK	
!
{"access_token":"e651bdf91e704c0f3d060ffd
4ff0403eb087f519","expires_in":
3600,"token_type":"bearer"}
アクセストークン取得
アクセストークン取得
GET /api/friends	
Authorization: Bear e651bdf91e704c0f3d060ffd4ff0403eb087f519
リソース取得
Spring Security OAuth
• Spring Securityの拡張でOAuthに対応
• 認証認可に加え、トークン管理、クライアン
ト管理等
• OAuth認可サーバー、クライアントの実装が簡単
• 標準のGrantTypeは用意済み。カスタム
GrantTypeも実装可能
Resource
Owner
Client
Resource
Server
Authorization
Server
Spring Security OAuth
サーバーの場合
Resource
Owner
Client
Resource
Server
Authorization
Server
OAuth2RestTemplate
Spring Security OAuth
クライアントの場合
Resource
Owner
Client
(curl) Resource
Server
(Bookmark)
Authorization
Server
ユーザー名・
パスワード
アクセストークン
Bookmark APIの例
<dependency>	
<groupId>org.springframework.security.oauth</
groupId>	
<artifactId>spring-security-oauth2</artifactId>	
<version>2.0.5.RELEASE</version>	
</dependency>
まだSpring Boot用の
AutoConfigure/Starterはない
Spring Securityの認証設定
@Configuration	
class WebSecurityConfiguration extends 	
GlobalAuthenticationConfigurerAdapter {	
@Autowired AccountRepository accountRepository;	
@Override	
public void init(AuthenticationManagerBuilder auth) 	
throws Exception {	
auth.userDetailsService(userDetailsService());	
}	
@Bean	
UserDetailsService userDetailsService() {	
return (username) -> accountRepository	
.findByUsername(username)	
.map(a -> new User(a.username, a.password	
, true, true, true, true,	
AuthorityUtils	
.createAuthorityList("USER", "write")))	
.orElseThrow(	
() -> new UsernameNotFoundException(…));	
}}
Spring Securityの認証設定
@Configuration	
class WebSecurityConfiguration extends 	
GlobalAuthenticationConfigurerAdapter {	
@Autowired AccountRepository accountRepository;	
@Override	
public void init(AuthenticationManagerBuilder auth) 	
throws Exception {	
auth.userDetailsService(userDetailsService());	
}	
@Bean	
UserDetailsService userDetailsService() {	
return (username) -> accountRepository	
.findByUsername(username)	
.map(a -> new User(a.username, a.password	
, true, true, true, true,	
AuthorityUtils	
.createAuthorityList("USER", "write")))	
.orElseThrow(	
() -> new UsernameNotFoundException(…));	
}}
ユーザー名から認証ユーザーを
取得するインタフェース
@Configuration @EnableResourceServer	
class OAuth2ResourceConfiguration extends	
ResourceServerConfigurerAdapter {	
@Override	
public void configure(ResourceServerSecurityConfigurer r) {	
r.resourceId("bookmarks");	
}	
@Override	
public void configure(HttpSecurity http) throws Exception {	
http.sessionManagement()	
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);	
http.authorizeRequests()	
.anyRequest().authenticated();	
}	
}
ResourceServerの設定
@Configuration @EnableResourceServer	
class OAuth2ResourceConfiguration extends	
ResourceServerConfigurerAdapter {	
@Override	
public void configure(ResourceServerSecurityConfigurer r) {	
r.resourceId("bookmarks");	
}	
@Override	
public void configure(HttpSecurity http) throws Exception {	
http.sessionManagement()	
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);	
http.authorizeRequests()	
.anyRequest().authenticated();	
}	
}
ResourceServerの設定
リソースID
@Configuration @EnableResourceServer	
class OAuth2ResourceConfiguration extends	
ResourceServerConfigurerAdapter {	
@Override	
public void configure(ResourceServerSecurityConfigurer r) {	
r.resourceId("bookmarks");	
}	
@Override	
public void configure(HttpSecurity http) throws Exception {	
http.sessionManagement()	
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);	
http.authorizeRequests()	
.anyRequest().authenticated();	
}	
}
ResourceServerの設定
リソースID
HTTPセッションを使わない!!
@Configuration @EnableResourceServer	
class OAuth2ResourceConfiguration extends	
ResourceServerConfigurerAdapter {	
@Override	
public void configure(ResourceServerSecurityConfigurer r) {	
r.resourceId("bookmarks");	
}	
@Override	
public void configure(HttpSecurity http) throws Exception {	
http.sessionManagement()	
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);	
http.authorizeRequests()	
.anyRequest().authenticated();	
}	
}
ResourceServerの設定
リソースID
HTTPセッションを使わない!!
認可設定
AuthorizationServerの設定
@Configuration @EnableAuthorizationServer

class OAuth2AuthorizationConfiguration 	
extends AuthorizationServerConfigurerAdapter {

@Autowired AuthenticationManager authenticationManager;

@Override

public void configure(AuthorizationServerEndpointsConfigurer ep)

throws Exception {

ep.authenticationManager(authenticationManager);

}

@Override

public void configure(ClientDetailsServiceConfigurer clients)	
throws Exception {

clients.inMemory().withClient("demoapp").secret("123456")

.authorizedGrantTypes("password", 	
"authorization_code",	
"refresh_token")

.authorities("ROLE_USER")

.scopes("write")	
.resourceIds("bookmarks");

}}
AuthorizationServerの設定
@Configuration @EnableAuthorizationServer

class OAuth2AuthorizationConfiguration 	
extends AuthorizationServerConfigurerAdapter {

@Autowired AuthenticationManager authenticationManager;

@Override

public void configure(AuthorizationServerEndpointsConfigurer ep)

throws Exception {

ep.authenticationManager(authenticationManager);

}

@Override

public void configure(ClientDetailsServiceConfigurer clients)	
throws Exception {

clients.inMemory().withClient("demoapp").secret("123456")

.authorizedGrantTypes("password", 	
"authorization_code",	
"refresh_token")

.authorities("ROLE_USER")

.scopes("write")	
.resourceIds("bookmarks");

}}
APIにアクセスするクライアントを登録
(今回はデモ用にインメモリ実装)
AuthorizationServerの設定
@Configuration @EnableAuthorizationServer

class OAuth2AuthorizationConfiguration 	
extends AuthorizationServerConfigurerAdapter {

@Autowired AuthenticationManager authenticationManager;

@Override

public void configure(AuthorizationServerEndpointsConfigurer ep)

throws Exception {

ep.authenticationManager(authenticationManager);

}

@Override

public void configure(ClientDetailsServiceConfigurer clients)	
throws Exception {

clients.inMemory().withClient("demoapp").secret("123456")

.authorizedGrantTypes("password", 	
"authorization_code",	
"refresh_token")

.authorities("ROLE_USER")

.scopes("write")	
.resourceIds("bookmarks");

}}
client_idとclient_secret
を設定
AuthorizationServerの設定
@Configuration @EnableAuthorizationServer

class OAuth2AuthorizationConfiguration 	
extends AuthorizationServerConfigurerAdapter {

@Autowired AuthenticationManager authenticationManager;

@Override

public void configure(AuthorizationServerEndpointsConfigurer ep)

throws Exception {

ep.authenticationManager(authenticationManager);

}

@Override

public void configure(ClientDetailsServiceConfigurer clients)	
throws Exception {

clients.inMemory().withClient("demoapp").secret("123456")

.authorizedGrantTypes("password", 	
"authorization_code",	
"refresh_token")

.authorities("ROLE_USER")

.scopes("write")	
.resourceIds("bookmarks");

}}
対象のclientに許可する
grant_typeを指定
AuthorizationServerの設定
@Configuration @EnableAuthorizationServer

class OAuth2AuthorizationConfiguration 	
extends AuthorizationServerConfigurerAdapter {

@Autowired AuthenticationManager authenticationManager;

@Override

public void configure(AuthorizationServerEndpointsConfigurer ep)

throws Exception {

ep.authenticationManager(authenticationManager);

}

@Override

public void configure(ClientDetailsServiceConfigurer clients)	
throws Exception {

clients.inMemory().withClient("demoapp").secret("123456")

.authorizedGrantTypes("password", 	
"authorization_code",	
"refresh_token")

.authorities("ROLE_USER")

.scopes("write")	
.resourceIds("bookmarks");

}}
対象のclientに許可する
ロールとスコープを指定
AuthorizationServerの設定
@Configuration @EnableAuthorizationServer

class OAuth2AuthorizationConfiguration 	
extends AuthorizationServerConfigurerAdapter {

@Autowired AuthenticationManager authenticationManager;

@Override

public void configure(AuthorizationServerEndpointsConfigurer ep)

throws Exception {

ep.authenticationManager(authenticationManager);

}

@Override

public void configure(ClientDetailsServiceConfigurer clients)	
throws Exception {

clients.inMemory().withClient("demoapp").secret("123456")

.authorizedGrantTypes("password", 	
"authorization_code",	
"refresh_token")

.authorities("ROLE_USER")

.scopes("write")	
.resourceIds("bookmarks");

}}
clientに対応する
リソースIDを指定
リソースアクセス
$ curl -v http://localhost:8080/bookmarks	
(略)	
< HTTP/1.1 401 Unauthorized	
(略)	
< WWW-Authenticate: Bearer realm="bookmarks",
error="unauthorized", error_description="An
Authentication object was not found in the
SecurityContext"	
(略)	
{"error_description": "An Authentication object
was not found in the SecurityContext","error":
"unauthorized"}
トークン発行
$ curl-X POST -u demoapp:123456 http://
localhost:8080/oauth/token -d
"password=password&username=making&grant_type=pa
ssword&scope=write"	
!
{"access_token":"5f4b1353-ddd0-431b-
a4b6-365267305d73","token_type":"bearer","refres
h_token":"a50e4f67-373c-4f62-
bdfb-560cf005d1e7","expires_in":
4292,"scope":"write"}
リソースアクセス
$ curl -H 'Authorization: Bearer 5f4b1353-
ddd0-431b-a4b6-365267305d73' http://localhost:
8080/bookmarks	
!
{	
"content": [	
{	
"links": […],	
"book": {…}	
}	
], …	
}
HTTPS対応
$ keytool -genkeypair -alias mytestkey -keyalg RSA -dname
"CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US"
-keypass changeme -keystore server.jks -storepass letmein
• 設定ファイル(application.yml)に
設定を書くだけで簡単SSL対応
server:	
port: 8443	
ssl:	
key-store: server.jks	
key-store-password: letmein	
key-password: changeme
いつも通り起動
$ mvn spring-boot:run	
… (略)	
2014-12-13 12:07:47.833 INFO --- [mple.App.main()]
s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started
on port(s): 8443/https	
2014-12-13 12:07:47.836 INFO --- [mple.App.main()]
com.example.App : Started App in
5.322 seconds (JVM running for 10.02)
いつも通り起動
$ mvn spring-boot:run	
… (略)	
2014-12-13 12:07:47.833 INFO --- [mple.App.main()]
s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started
on port(s): 8443/https	
2014-12-13 12:07:47.836 INFO --- [mple.App.main()]
com.example.App : Started App in
5.322 seconds (JVM running for 10.02)
Spring Security OAuthで
ステートレスにRESTを
セキュア化!!
Spring Security OAuthで
ステートレスにRESTを
セキュア化!!
スケールブル!!
Spring Security OAuthで
ステートレスにRESTを
セキュア化!!
スケールブル!!
って思うやん?
https://spring.io/blog/2015/01/12/the-login-page-angular-js-and-spring-security-part-ii#help-how-is-my-application-going-to-scale
https://spring.io/blog/2015/01/12/the-login-page-angular-js-and-spring-security-part-ii#help-how-is-my-application-going-to-scale
いつまで"ステートレス"
で消耗してんの?
(意訳 違訳)
https://spring.io/blog/2015/01/12/the-login-page-angular-js-and-spring-security-part-ii#help-how-is-my-application-going-to-scale
いつまで"ステートレス"
で消耗してんの?
(意訳 違訳)
https://spring.io/blog/2015/01/12/the-login-page-angular-js-and-spring-security-part-ii#help-how-is-my-application-going-to-scale
いつまで"ステートレス"
で消耗してんの?
(意訳 違訳)
セキュリティ対策は何やかんや
でステートフル
(CSRFトークンとか。アクセストークンだっ
て広い意味でステート)
これまでのHttpSession
を使う場合
HttpSessionのデータを
APサーバーのメモリに保存
ロードバランサのSticky Sessionで
同じSessionを同一JVMにバインド
Spring Session
• セッションデータをJVM間で共有する新しい
選択肢
• 新しいセッションAPI
• HttpSessionと統合して、以下を提供
• Clustered Session
• Multiple Browser Sessions
• RESTful APIs
• WebSocketにも対応
Spring Session
• セッションデータをJVM間で共有する新しい
選択肢
• 新しいセッションAPI
• HttpSessionと統合して、以下を提供
• Clustered Session
• Multiple Browser Sessions
• RESTful APIs
• WebSocketにも対応
ServletRequest/Response、
HttpSessionをラップする
Servlet Filterを提供
Clustered Session
• KVSをつかったセッション
• Redis実装が提供されている
• アプリを跨いだセッション共有も可能
@Import(EmbeddedRedisConfiguration.class)	
@EnableRedisHttpSession 	
public class SessionConfig {	
@Bean	
JedisConnectionFactory 	
connectionFactory() {	
return new JedisConnectionFactory(); 	
}	
}
public class SessionInitializer extends	
AbstractHttpSessionApplicationInitializer {
!
public SessionInitializer() {	
super(SessionConfig.class); 	
}	
}
<dependency>

<groupId>org.springframework.session</groupId>

<artifactId>spring-session</artifactId>

<version>1.0.0.RELEASE</version>

</dependency>

<dependency>

<groupId>org.springframework.session</groupId>

<artifactId>spring-session-data-redis</artifactId>

<version>1.0.0.RELEASE</version>

</dependency>
Multiple Browser Sessions
割愛
HttpSession & RESTful APIs
Cookie(JSESSIONID)の代わりに
HTTPヘッダ(X-AUTH-TOKEN)に
セッション情報を載せる
@Import(EmbeddedRedisConfiguration.class)	
@EnableRedisHttpSession 	
public class SessionConfig {	
@Bean	
JedisConnectionFactory 	
connectionFactory() {	
return new JedisConnectionFactory(); 	
} 	
@Bean	
HttpSessionStrategy	
httpSessionStrategy() {	
return new HeaderHttpSessionStrategy(); 	
}	
}
class MvcInitializer extends 	
AbstractAnnotationConfigDispatcherServletInitializer {	
@Override	
protected Class<?>[] 	
getRootConfigClasses() {	
return new Class[] {	
SessionConfig.class, …};	
// …	
}
$ curl -v http://localhost:8080/ -u
user:password	
!
HTTP/1.1 200 OK	
(略)	
x-auth-token: 0dc1f6e1-
c7f1-41ac-8ce2-32b6b3e57aa3	
!
{"username":"user"}
$ curl -v http://localhost:8080/ -H "x-
auth-token: 0dc1f6e1-
c7f1-41ac-8ce2-32b6b3e57aa3"
Spring Bootを使うと
@EnableRedisHttpSession

class HttpSessionConfig {

@Bean

HttpSessionStrategy 	
httpSessionStrategy() {

return new HeaderHttpSessionStrategy();

}

}
Spring Bootを使うと
@EnableRedisHttpSession

class HttpSessionConfig {

@Bean

HttpSessionStrategy 	
httpSessionStrategy() {

return new HeaderHttpSessionStrategy();

}

}
これだけ!
(Redisの設定も不要)
認可設定
@Configuration @EnableWebSecurity

class SecurityConfig extends
WebSecurityConfigurerAdapter {

@Override

protected void configure(HttpSecurity
http) throws Exception {

http.authorizeRequests()

.anyRequest().authenticated()

.and().httpBasic();

}

}
サンプルコントローラー
@RestController

class AuthController {

@RequestMapping

String check(Principal principal) {

return principal.getName();

}

}
$ curl -v http://localhost:8080/ -u
making:password	
!
HTTP/1.1 200 OK	
(略)	
x-auth-token: fe1b6d11-9867-4df2-b5bf-
a33eb004ac65	
!
making
$ curl -v http://localhost:8080/ -u
making:password	
!
HTTP/1.1 200 OK	
(略)	
x-auth-token: fe1b6d11-9867-4df2-b5bf-
a33eb004ac65	
!
making
$ curl -v -H 'x-auth-token:
fe1b6d11-9867-4df2-b5bf-a33eb004ac65'
http://localhost:8080/bookmarks	
!
{"_embedded": {"bookmarkResourceList":
[{"_links": {…,"bookmark-uri": {	
"href": "http://bookmark.com/1/
making"}},…}]
APIを3rdパーティに提供したい場合以外、
Spring Session使えばいいんじゃないか?
まとめ
• Spring Boot概要
• RESTについていろいろ
• Richardson Maturity Model / HATEOAS
• JSON-Patch
• Security (OAuth/Spring Session)
Q&A?
• はじめてのSpring Boot
• http://bit.ly/hajiboot
• 今日話した内容のチュートリアル
• http://spring.io/guides/tutorials/bookmarks
• 今日のソースコード
• https://github.com/making/tut-bookmarks

More Related Content

What's hot

laravel x モバイルアプリ
laravel x モバイルアプリlaravel x モバイルアプリ
laravel x モバイルアプリMasaki Oshikawa
 
はじめてのSpring Boot
はじめてのSpring BootはじめてのSpring Boot
はじめてのSpring Bootなべ
 
Service workerとwebプッシュ通知
Service workerとwebプッシュ通知Service workerとwebプッシュ通知
Service workerとwebプッシュ通知zaru sakuraba
 
Spring Fest 2018 Spring Bootで作るRESTful Web Service
Spring Fest 2018 Spring Bootで作るRESTful Web ServiceSpring Fest 2018 Spring Bootで作るRESTful Web Service
Spring Fest 2018 Spring Bootで作るRESTful Web ServiceWataruOhno
 
Spring integration概要
Spring integration概要Spring integration概要
Spring integration概要kuroiwa
 
Laravel5を使って開発してみた
Laravel5を使って開発してみたLaravel5を使って開発してみた
Laravel5を使って開発してみたTakeo Noda
 
Service worker が拓く mobile web の新しいかたち
Service worker が拓く mobile web の新しいかたちService worker が拓く mobile web の新しいかたち
Service worker が拓く mobile web の新しいかたちKinuko Yasuda
 
React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDEdcubeio
 
Spring Bootキャンプ @関ジャバ #kanjava_sbc
Spring Bootキャンプ @関ジャバ #kanjava_sbcSpring Bootキャンプ @関ジャバ #kanjava_sbc
Spring Bootキャンプ @関ジャバ #kanjava_sbcToshiaki Maki
 
React入門-JSONを取得して表示する
React入門-JSONを取得して表示するReact入門-JSONを取得して表示する
React入門-JSONを取得して表示するregret raym
 
Spring data-rest-and-spring-cloud-contract
Spring data-rest-and-spring-cloud-contractSpring data-rest-and-spring-cloud-contract
Spring data-rest-and-spring-cloud-contractTakeshi Ogawa
 
behatエクステンションの作り方
behatエクステンションの作り方behatエクステンションの作り方
behatエクステンションの作り方Ryo Tomidokoro
 
Laravelの認証について
Laravelの認証についてLaravelの認証について
Laravelの認証についてTakeo Noda
 
Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス
Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティスJsug2015 summer spring適用におけるバッドノウハウとベタープラクティス
Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティスYoichi KIKUCHI
 
こんなに使える!今どきのAPIドキュメンテーションツール
こんなに使える!今どきのAPIドキュメンテーションツールこんなに使える!今どきのAPIドキュメンテーションツール
こんなに使える!今どきのAPIドキュメンテーションツールdcubeio
 
アメブロ2016 アメブロフロント刷新にみる ひかりとつらみ
アメブロ2016 アメブロフロント刷新にみる ひかりとつらみアメブロ2016 アメブロフロント刷新にみる ひかりとつらみ
アメブロ2016 アメブロフロント刷新にみる ひかりとつらみKazunari Hara
 

What's hot (20)

laravel x モバイルアプリ
laravel x モバイルアプリlaravel x モバイルアプリ
laravel x モバイルアプリ
 
はじめてのSpring Boot
はじめてのSpring BootはじめてのSpring Boot
はじめてのSpring Boot
 
APIMeetup 20170329_ichimura
APIMeetup 20170329_ichimuraAPIMeetup 20170329_ichimura
APIMeetup 20170329_ichimura
 
Service workerとwebプッシュ通知
Service workerとwebプッシュ通知Service workerとwebプッシュ通知
Service workerとwebプッシュ通知
 
Spring Fest 2018 Spring Bootで作るRESTful Web Service
Spring Fest 2018 Spring Bootで作るRESTful Web ServiceSpring Fest 2018 Spring Bootで作るRESTful Web Service
Spring Fest 2018 Spring Bootで作るRESTful Web Service
 
Spring integration概要
Spring integration概要Spring integration概要
Spring integration概要
 
Laravel5を使って開発してみた
Laravel5を使って開発してみたLaravel5を使って開発してみた
Laravel5を使って開発してみた
 
Grails 2.0.0.M1の話
Grails 2.0.0.M1の話 Grails 2.0.0.M1の話
Grails 2.0.0.M1の話
 
Service worker が拓く mobile web の新しいかたち
Service worker が拓く mobile web の新しいかたちService worker が拓く mobile web の新しいかたち
Service worker が拓く mobile web の新しいかたち
 
React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDE
 
Spring Bootキャンプ @関ジャバ #kanjava_sbc
Spring Bootキャンプ @関ジャバ #kanjava_sbcSpring Bootキャンプ @関ジャバ #kanjava_sbc
Spring Bootキャンプ @関ジャバ #kanjava_sbc
 
REACT & WEB API
REACT & WEB APIREACT & WEB API
REACT & WEB API
 
React入門-JSONを取得して表示する
React入門-JSONを取得して表示するReact入門-JSONを取得して表示する
React入門-JSONを取得して表示する
 
Spring data-rest-and-spring-cloud-contract
Spring data-rest-and-spring-cloud-contractSpring data-rest-and-spring-cloud-contract
Spring data-rest-and-spring-cloud-contract
 
behatエクステンションの作り方
behatエクステンションの作り方behatエクステンションの作り方
behatエクステンションの作り方
 
Laravelの認証について
Laravelの認証についてLaravelの認証について
Laravelの認証について
 
Spring と TDD
Spring と TDDSpring と TDD
Spring と TDD
 
Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス
Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティスJsug2015 summer spring適用におけるバッドノウハウとベタープラクティス
Jsug2015 summer spring適用におけるバッドノウハウとベタープラクティス
 
こんなに使える!今どきのAPIドキュメンテーションツール
こんなに使える!今どきのAPIドキュメンテーションツールこんなに使える!今どきのAPIドキュメンテーションツール
こんなに使える!今どきのAPIドキュメンテーションツール
 
アメブロ2016 アメブロフロント刷新にみる ひかりとつらみ
アメブロ2016 アメブロフロント刷新にみる ひかりとつらみアメブロ2016 アメブロフロント刷新にみる ひかりとつらみ
アメブロ2016 アメブロフロント刷新にみる ひかりとつらみ
 

Viewers also liked

Microservices with Spring Boot
Microservices with Spring BootMicroservices with Spring Boot
Microservices with Spring BootJoshua Long
 
実例で学ぶ、明日から使えるSpring Boot Tips #jsug
実例で学ぶ、明日から使えるSpring Boot Tips #jsug実例で学ぶ、明日から使えるSpring Boot Tips #jsug
実例で学ぶ、明日から使えるSpring Boot Tips #jsugToshiaki Maki
 
Microservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring CloudMicroservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring CloudEberhard Wolff
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introductionRasheed Waraich
 
#jjug_ccc #ccc_gh5 What's new in Spring Framework 4.3 / Boot 1.4 + Pivotal's ...
#jjug_ccc #ccc_gh5 What's new in Spring Framework 4.3 / Boot 1.4 + Pivotal's ...#jjug_ccc #ccc_gh5 What's new in Spring Framework 4.3 / Boot 1.4 + Pivotal's ...
#jjug_ccc #ccc_gh5 What's new in Spring Framework 4.3 / Boot 1.4 + Pivotal's ...Toshiaki Maki
 
Grails 3.0先取り!? Spring Boot入門ハンズオン #jggug_boot
Grails 3.0先取り!? Spring Boot入門ハンズオン #jggug_bootGrails 3.0先取り!? Spring Boot入門ハンズオン #jggug_boot
Grails 3.0先取り!? Spring Boot入門ハンズオン #jggug_bootToshiaki Maki
 
Spring Bootをはじめる時にやるべき10のこと
Spring Bootをはじめる時にやるべき10のことSpring Bootをはじめる時にやるべき10のこと
Spring Bootをはじめる時にやるべき10のこと心 谷本
 
Microservice With Spring Boot and Spring Cloud
Microservice With Spring Boot and Spring CloudMicroservice With Spring Boot and Spring Cloud
Microservice With Spring Boot and Spring CloudEberhard Wolff
 
Spring boot
Spring bootSpring boot
Spring bootsdeeg
 
Spring tutorial
Spring tutorialSpring tutorial
Spring tutorialPhuong Le
 
Spring tutorial
Spring tutorialSpring tutorial
Spring tutorialmamog
 
Building a REST Service in minutes with Spring Boot
Building a REST Service in minutes with Spring BootBuilding a REST Service in minutes with Spring Boot
Building a REST Service in minutes with Spring BootOmri Spector
 
Spring Web Service, Spring Integration and Spring Batch
Spring Web Service, Spring Integration and Spring BatchSpring Web Service, Spring Integration and Spring Batch
Spring Web Service, Spring Integration and Spring BatchEberhard Wolff
 
最近のSpringFramework2013 #jjug #jsug #SpringFramework
最近のSpringFramework2013 #jjug #jsug #SpringFramework最近のSpringFramework2013 #jjug #jsug #SpringFramework
最近のSpringFramework2013 #jjug #jsug #SpringFrameworkToshiaki Maki
 

Viewers also liked (20)

Microservices with Spring Boot
Microservices with Spring BootMicroservices with Spring Boot
Microservices with Spring Boot
 
実例で学ぶ、明日から使えるSpring Boot Tips #jsug
実例で学ぶ、明日から使えるSpring Boot Tips #jsug実例で学ぶ、明日から使えるSpring Boot Tips #jsug
実例で学ぶ、明日から使えるSpring Boot Tips #jsug
 
Microservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring CloudMicroservices with Java, Spring Boot and Spring Cloud
Microservices with Java, Spring Boot and Spring Cloud
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
Spring boot
Spring bootSpring boot
Spring boot
 
#jjug_ccc #ccc_gh5 What's new in Spring Framework 4.3 / Boot 1.4 + Pivotal's ...
#jjug_ccc #ccc_gh5 What's new in Spring Framework 4.3 / Boot 1.4 + Pivotal's ...#jjug_ccc #ccc_gh5 What's new in Spring Framework 4.3 / Boot 1.4 + Pivotal's ...
#jjug_ccc #ccc_gh5 What's new in Spring Framework 4.3 / Boot 1.4 + Pivotal's ...
 
Spring Boot Tutorial
Spring Boot TutorialSpring Boot Tutorial
Spring Boot Tutorial
 
Grails 3.0先取り!? Spring Boot入門ハンズオン #jggug_boot
Grails 3.0先取り!? Spring Boot入門ハンズオン #jggug_bootGrails 3.0先取り!? Spring Boot入門ハンズオン #jggug_boot
Grails 3.0先取り!? Spring Boot入門ハンズオン #jggug_boot
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Spring Bootをはじめる時にやるべき10のこと
Spring Bootをはじめる時にやるべき10のことSpring Bootをはじめる時にやるべき10のこと
Spring Bootをはじめる時にやるべき10のこと
 
Microservice With Spring Boot and Spring Cloud
Microservice With Spring Boot and Spring CloudMicroservice With Spring Boot and Spring Cloud
Microservice With Spring Boot and Spring Cloud
 
Spring boot
Spring bootSpring boot
Spring boot
 
Rest with Spring
Rest with SpringRest with Spring
Rest with Spring
 
Spring tutorial
Spring tutorialSpring tutorial
Spring tutorial
 
Spring tutorial
Spring tutorialSpring tutorial
Spring tutorial
 
Building a REST Service in minutes with Spring Boot
Building a REST Service in minutes with Spring BootBuilding a REST Service in minutes with Spring Boot
Building a REST Service in minutes with Spring Boot
 
Spring Batch 2.0
Spring Batch 2.0Spring Batch 2.0
Spring Batch 2.0
 
Android ios
Android iosAndroid ios
Android ios
 
Spring Web Service, Spring Integration and Spring Batch
Spring Web Service, Spring Integration and Spring BatchSpring Web Service, Spring Integration and Spring Batch
Spring Web Service, Spring Integration and Spring Batch
 
最近のSpringFramework2013 #jjug #jsug #SpringFramework
最近のSpringFramework2013 #jjug #jsug #SpringFramework最近のSpringFramework2013 #jjug #jsug #SpringFramework
最近のSpringFramework2013 #jjug #jsug #SpringFramework
 

Similar to REST with Spring Boot #jqfk

Springでdao 20070413
Springでdao 20070413Springでdao 20070413
Springでdao 20070413Funato Takashi
 
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframeworkSpring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframeworkToshiaki Maki
 
サンプルアプリケーションで学ぶApache Cassandraを使ったJavaアプリケーションの作り方
サンプルアプリケーションで学ぶApache Cassandraを使ったJavaアプリケーションの作り方サンプルアプリケーションで学ぶApache Cassandraを使ったJavaアプリケーションの作り方
サンプルアプリケーションで学ぶApache Cassandraを使ったJavaアプリケーションの作り方Yuki Morishita
 
Head toward Java 16 (Night Seminar Edition)
Head toward Java 16 (Night Seminar Edition)Head toward Java 16 (Night Seminar Edition)
Head toward Java 16 (Night Seminar Edition)Yuji Kubota
 
Struts2を始めよう!
Struts2を始めよう!Struts2を始めよう!
Struts2を始めよう!Shinpei Ohtani
 
企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624Yusuke Suzuki
 
Automatic api document generation 101
Automatic api document generation 101Automatic api document generation 101
Automatic api document generation 101LINE Corporation
 
徳島OSS勉強会第四回 シラサギハンズオン 0925
徳島OSS勉強会第四回 シラサギハンズオン 0925徳島OSS勉強会第四回 シラサギハンズオン 0925
徳島OSS勉強会第四回 シラサギハンズオン 0925Yu Ito
 
Spring Rooで作るGWTアプリケーション
Spring Rooで作るGWTアプリケーションSpring Rooで作るGWTアプリケーション
Spring Rooで作るGWTアプリケーションToshiaki Maki
 
Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう
Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみようAlfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう
Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみようTasuku Otani
 
Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理土岐 孝平
 
かんたん Twitter アプリをつくろう
かんたん Twitter アプリをつくろう かんたん Twitter アプリをつくろう
かんたん Twitter アプリをつくろう Shuhei Iitsuka
 
Jjug springセッション
Jjug springセッションJjug springセッション
Jjug springセッションYuichi Hasegawa
 
[使い倒し]GitHubのIssueとTFS/VSOのWorkItem連動に挑む(2015/08/26)
[使い倒し]GitHubのIssueとTFS/VSOのWorkItem連動に挑む(2015/08/26)[使い倒し]GitHubのIssueとTFS/VSOのWorkItem連動に挑む(2015/08/26)
[使い倒し]GitHubのIssueとTFS/VSOのWorkItem連動に挑む(2015/08/26)Masanori Ishigami
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platformToru Yamaguchi
 
JavaOne2015報告またはこれからのJava
JavaOne2015報告またはこれからのJavaJavaOne2015報告またはこれからのJava
JavaOne2015報告またはこれからのJavaなおき きしだ
 
Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略takezoe
 

Similar to REST with Spring Boot #jqfk (20)

Springでdao 20070413
Springでdao 20070413Springでdao 20070413
Springでdao 20070413
 
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframeworkSpring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
 
サンプルアプリケーションで学ぶApache Cassandraを使ったJavaアプリケーションの作り方
サンプルアプリケーションで学ぶApache Cassandraを使ったJavaアプリケーションの作り方サンプルアプリケーションで学ぶApache Cassandraを使ったJavaアプリケーションの作り方
サンプルアプリケーションで学ぶApache Cassandraを使ったJavaアプリケーションの作り方
 
Head toward Java 16 (Night Seminar Edition)
Head toward Java 16 (Night Seminar Edition)Head toward Java 16 (Night Seminar Edition)
Head toward Java 16 (Night Seminar Edition)
 
Struts2を始めよう!
Struts2を始めよう!Struts2を始めよう!
Struts2を始めよう!
 
企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624
 
Automatic api document generation 101
Automatic api document generation 101Automatic api document generation 101
Automatic api document generation 101
 
徳島OSS勉強会第四回 シラサギハンズオン 0925
徳島OSS勉強会第四回 シラサギハンズオン 0925徳島OSS勉強会第四回 シラサギハンズオン 0925
徳島OSS勉強会第四回 シラサギハンズオン 0925
 
Spring Rooで作るGWTアプリケーション
Spring Rooで作るGWTアプリケーションSpring Rooで作るGWTアプリケーション
Spring Rooで作るGWTアプリケーション
 
Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう
Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみようAlfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう
Alfresco勉強会#36 alfresco 5でカスタムREST APIを作ってみよう
 
Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理
 
かんたん Twitter アプリをつくろう
かんたん Twitter アプリをつくろう かんたん Twitter アプリをつくろう
かんたん Twitter アプリをつくろう
 
ASP.NET MVC 1.0
ASP.NET MVC 1.0ASP.NET MVC 1.0
ASP.NET MVC 1.0
 
Jjug springセッション
Jjug springセッションJjug springセッション
Jjug springセッション
 
HTML5&API総まくり
HTML5&API総まくりHTML5&API総まくり
HTML5&API総まくり
 
Haikara
HaikaraHaikara
Haikara
 
[使い倒し]GitHubのIssueとTFS/VSOのWorkItem連動に挑む(2015/08/26)
[使い倒し]GitHubのIssueとTFS/VSOのWorkItem連動に挑む(2015/08/26)[使い倒し]GitHubのIssueとTFS/VSOのWorkItem連動に挑む(2015/08/26)
[使い倒し]GitHubのIssueとTFS/VSOのWorkItem連動に挑む(2015/08/26)
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platform
 
JavaOne2015報告またはこれからのJava
JavaOne2015報告またはこれからのJavaJavaOne2015報告またはこれからのJava
JavaOne2015報告またはこれからのJava
 
Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略
 

More from Toshiaki Maki

From Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsugFrom Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsugToshiaki Maki
 
Concourse x Spinnaker #concourse_tokyo
Concourse x Spinnaker #concourse_tokyoConcourse x Spinnaker #concourse_tokyo
Concourse x Spinnaker #concourse_tokyoToshiaki Maki
 
Serverless with Spring Cloud Function, Knative and riff #SpringOneTour #s1t
Serverless with Spring Cloud Function, Knative and riff #SpringOneTour #s1tServerless with Spring Cloud Function, Knative and riff #SpringOneTour #s1t
Serverless with Spring Cloud Function, Knative and riff #SpringOneTour #s1tToshiaki Maki
 
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1Toshiaki Maki
 
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1Toshiaki Maki
 
Spring Boot Actuator 2.0 & Micrometer
Spring Boot Actuator 2.0 & MicrometerSpring Boot Actuator 2.0 & Micrometer
Spring Boot Actuator 2.0 & MicrometerToshiaki Maki
 
Open Service Broker APIとKubernetes Service Catalog #k8sjp
Open Service Broker APIとKubernetes Service Catalog #k8sjpOpen Service Broker APIとKubernetes Service Catalog #k8sjp
Open Service Broker APIとKubernetes Service Catalog #k8sjpToshiaki Maki
 
Spring Cloud Function & Project riff #jsug
Spring Cloud Function & Project riff #jsugSpring Cloud Function & Project riff #jsug
Spring Cloud Function & Project riff #jsugToshiaki Maki
 
Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Toshiaki Maki
 
BOSH / CF Deployment in modern ways #cf_tokyo
BOSH / CF Deployment in modern ways #cf_tokyoBOSH / CF Deployment in modern ways #cf_tokyo
BOSH / CF Deployment in modern ways #cf_tokyoToshiaki Maki
 
Why PCF is the best platform for Spring Boot
Why PCF is the best platform for Spring BootWhy PCF is the best platform for Spring Boot
Why PCF is the best platform for Spring BootToshiaki Maki
 
Zipkin Components #zipkin_jp
Zipkin Components #zipkin_jpZipkin Components #zipkin_jp
Zipkin Components #zipkin_jpToshiaki Maki
 
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07Toshiaki Maki
 
Spring Framework 5.0による Reactive Web Application #JavaDayTokyo
Spring Framework 5.0による Reactive Web Application #JavaDayTokyoSpring Framework 5.0による Reactive Web Application #JavaDayTokyo
Spring Framework 5.0による Reactive Web Application #JavaDayTokyoToshiaki Maki
 
Spring ❤️ Kotlin #jjug
Spring ❤️ Kotlin #jjugSpring ❤️ Kotlin #jjug
Spring ❤️ Kotlin #jjugToshiaki Maki
 
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3Toshiaki Maki
 
Managing your Docker image continuously with Concourse CI
Managing your Docker image continuously with Concourse CIManaging your Docker image continuously with Concourse CI
Managing your Docker image continuously with Concourse CIToshiaki Maki
 
Data Microservices with Spring Cloud Stream, Task, and Data Flow #jsug #spri...
Data Microservices with Spring Cloud Stream, Task,  and Data Flow #jsug #spri...Data Microservices with Spring Cloud Stream, Task,  and Data Flow #jsug #spri...
Data Microservices with Spring Cloud Stream, Task, and Data Flow #jsug #spri...Toshiaki Maki
 
Short Lived Tasks in Cloud Foundry #cfdtokyo
Short Lived Tasks in Cloud Foundry #cfdtokyoShort Lived Tasks in Cloud Foundry #cfdtokyo
Short Lived Tasks in Cloud Foundry #cfdtokyoToshiaki Maki
 
今すぐ始めるCloud Foundry #hackt #hackt_k
今すぐ始めるCloud Foundry #hackt #hackt_k今すぐ始めるCloud Foundry #hackt #hackt_k
今すぐ始めるCloud Foundry #hackt #hackt_kToshiaki Maki
 

More from Toshiaki Maki (20)

From Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsugFrom Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsug
 
Concourse x Spinnaker #concourse_tokyo
Concourse x Spinnaker #concourse_tokyoConcourse x Spinnaker #concourse_tokyo
Concourse x Spinnaker #concourse_tokyo
 
Serverless with Spring Cloud Function, Knative and riff #SpringOneTour #s1t
Serverless with Spring Cloud Function, Knative and riff #SpringOneTour #s1tServerless with Spring Cloud Function, Knative and riff #SpringOneTour #s1t
Serverless with Spring Cloud Function, Knative and riff #SpringOneTour #s1t
 
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1
 
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
 
Spring Boot Actuator 2.0 & Micrometer
Spring Boot Actuator 2.0 & MicrometerSpring Boot Actuator 2.0 & Micrometer
Spring Boot Actuator 2.0 & Micrometer
 
Open Service Broker APIとKubernetes Service Catalog #k8sjp
Open Service Broker APIとKubernetes Service Catalog #k8sjpOpen Service Broker APIとKubernetes Service Catalog #k8sjp
Open Service Broker APIとKubernetes Service Catalog #k8sjp
 
Spring Cloud Function & Project riff #jsug
Spring Cloud Function & Project riff #jsugSpring Cloud Function & Project riff #jsug
Spring Cloud Function & Project riff #jsug
 
Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1
 
BOSH / CF Deployment in modern ways #cf_tokyo
BOSH / CF Deployment in modern ways #cf_tokyoBOSH / CF Deployment in modern ways #cf_tokyo
BOSH / CF Deployment in modern ways #cf_tokyo
 
Why PCF is the best platform for Spring Boot
Why PCF is the best platform for Spring BootWhy PCF is the best platform for Spring Boot
Why PCF is the best platform for Spring Boot
 
Zipkin Components #zipkin_jp
Zipkin Components #zipkin_jpZipkin Components #zipkin_jp
Zipkin Components #zipkin_jp
 
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
 
Spring Framework 5.0による Reactive Web Application #JavaDayTokyo
Spring Framework 5.0による Reactive Web Application #JavaDayTokyoSpring Framework 5.0による Reactive Web Application #JavaDayTokyo
Spring Framework 5.0による Reactive Web Application #JavaDayTokyo
 
Spring ❤️ Kotlin #jjug
Spring ❤️ Kotlin #jjugSpring ❤️ Kotlin #jjug
Spring ❤️ Kotlin #jjug
 
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
 
Managing your Docker image continuously with Concourse CI
Managing your Docker image continuously with Concourse CIManaging your Docker image continuously with Concourse CI
Managing your Docker image continuously with Concourse CI
 
Data Microservices with Spring Cloud Stream, Task, and Data Flow #jsug #spri...
Data Microservices with Spring Cloud Stream, Task,  and Data Flow #jsug #spri...Data Microservices with Spring Cloud Stream, Task,  and Data Flow #jsug #spri...
Data Microservices with Spring Cloud Stream, Task, and Data Flow #jsug #spri...
 
Short Lived Tasks in Cloud Foundry #cfdtokyo
Short Lived Tasks in Cloud Foundry #cfdtokyoShort Lived Tasks in Cloud Foundry #cfdtokyo
Short Lived Tasks in Cloud Foundry #cfdtokyo
 
今すぐ始めるCloud Foundry #hackt #hackt_k
今すぐ始めるCloud Foundry #hackt #hackt_k今すぐ始めるCloud Foundry #hackt #hackt_k
今すぐ始めるCloud Foundry #hackt #hackt_k
 

Recently uploaded

スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directoryosamut
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxAtomu Hidaka
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
UPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdfUPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdffurutsuka
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000Shota Ito
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 

Recently uploaded (9)

スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
 
UPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdfUPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdf
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
 

REST with Spring Boot #jqfk