SlideShare une entreprise Scribd logo
1  sur  29
Spotify Web API Object
modelを使ってMVCアプリを
設計してみましょう(1)
マッシュアップしたWeb APIのモデルをKey-Value storeに永続化
Web API編
自己紹介 髙尾 哲朗
システム構築のプロセス評価、改善、策定、開発フレームワークの設計、実装
管理、プリセールスやプロジェクトの立ち上げなど
ブログ : http://blog.processtune.com
プロフィール :Tetsuro Takao on Facebook, Twitter or
http://mvp.microsoft.com
コミュニティ :.NETラボの運営スタッフ https://dotnetlab.connpass.com
Microsoft MVP:Developer Technologies [July 2010 – June 2020]
本日のお話しするサンプルについて
1)解説はSpotifyを使用していますが、MVCとしてオ
ブジェクトモデルを使うようなアプリケーションで
あれば設計手法は流用できます。
2)Key-Value storeを使用していますが、永続化層は
本題ではありませんので使い慣れているものに置き
換えて流用ください。
3)マイクロ・サービスを題材にしていますが、マイク
ロ・サービスに限った設計方法ではありません。
4)MVC設計パターンのインプリメンテーションの一
例をお話しします。
サンプル・シナリオ
Web API
マッシュアップ部分 既存部分
…
…
… …
…
…
DB
ビュー
ステートフル・ミドルウェア
Value
Key
Value
Key
Actor
Spotify Web API Object Model
https://developer.spotify.com/documentation/web-api/reference/object-model/
Deserialize Object
var currentUser = JsonConvert.DeserializeObject<SpotifyUser>(getMe);
Spotify User Object Model
Type Resolver
Spotify Swagger.yaml
https://github.com/APIs-guru/openapi-directory/blob/master/APIs/spotify.com/v1/swagger.yaml
Swagger UI
https://swagger.io/tools/swagger-ui/
NSwag と ASP.NET Core の概要
https://docs.microsoft.com/ja-jp/aspnet/core/tutorials/getting-started-with-nswag?view=aspnetcore-3.
0&tabs=visual-studio
YamlDotNet
https://github.com/aaubry/YamlDotNet
YamlDotNetをインストール
public Tuple<string, List<Tuple<string, string>>> GetType(string objectName)
{
Tuple<string, List<Tuple<string, string>>> result = null;
var client = new WebClient();
var yamlAddress = new Configuration().Get("SpotifyYaml");
string yamlText = client.DownloadString("https://" + yamlAddress);
var input = new StringReader(yamlText);
var yaml = new YamlStream();
yaml.Load(input);
var mapping =(YamlMappingNode)yaml.Documents[0].RootNode;
var spotifyObjects = new List<Tuple<string, List<Tuple<string,string>>>>();
foreach (var entry in mapping.Children)
{
if (entry.Key.ToString()== "definitions")
{
var classes = (entry.Value as YamlMappingNode).Children.Keys;
foreach (var n in (entry.Value as YamlMappingNode).Children)
{
List <Tuple<string, string>> propertiesTemp = new List<Tuple<string, string>>();
foreach (var cn in (n.Value as YamlMappingNode).Children)
{
if (cn.Key.ToString() == "properties")
{
var properties = (cn.Value as YamlMappingNode).Children.Keys;
Tuple<string, string> temp = null;
foreach (var gcn in (cn.Value as YamlMappingNode).Children)
{
var tempVal = string.Empty;
if ((gcn.Value as YamlMappingNode).Children.Where(c => c.Key.ToString() == "type").Count() > 0)
{
tempVal = (gcn.Value as YamlMappingNode).Children.Where(c => c.Key.ToString() == "type").FirstOrDefault().Value.ToString();
temp = new Tuple<string, string>(gcn.Key.ToString(), tempVal);
propertiesTemp.Add(temp);
}
else if ((gcn.Value as YamlMappingNode).Children.Where(c => c.Key.ToString() == "$ref").Count() > 0)
{
tempVal = (gcn.Value as YamlMappingNode).Children.Where(c => c.Key.ToString() == "$ref").FirstOrDefault().Value.ToString();
tempVal = tempVal.Replace("#/definitions/", "");
tempVal = tempVal.Replace("'", "");
temp = new Tuple<string, string>(gcn.Key.ToString(), tempVal);
propertiesTemp.Add(temp);
}
}
break;
}
}
spotifyObjects.Add(new Tuple<string, List<Tuple<string, string>>>(n.Key.ToString(), propertiesTemp));
}
}
}
result = spotifyObjects.Where(r => r.Item1 == objectName).FirstOrDefault();
return result;
}
public Tuple<string, List<Tuple<string, string>>> GetType(string objectName)
var yamlAddress = new Configuration().Get("SpotifyYaml");
string yamlText = client.DownloadString("https://" + yamlAddress);
var yaml = new YamlStream();
yaml.Load(input);
var mapping =(YamlMappingNode)yaml.Documents[0].RootNode;
foreach (var entry in mapping.Children)
{
if (entry.Key.ToString()== "definitions")
{
var classes = (entry.Value as YamlMappingNode).Children.Keys;
foreach (var n in (entry.Value as YamlMappingNode).Children)
{
var propertiesTemp = new List<Tuple<string, string>>();
foreach (var cn in (n.Value as YamlMappingNode).Children)
{
if (cn.Key.ToString() == "properties")
public Tuple<string, List<Tuple<string, string>>> GetType(string objectName)
{
Tuple<string, List<Tuple<string, string>>> result = null;
var client = new WebClient();
var yamlAddress = new Configuration().Get("SpotifyYaml");
string yamlText = client.DownloadString("https://" + yamlAddress);
var input = new StringReader(yamlText);
var yaml = new YamlStream();
yaml.Load(input);
var mapping =(YamlMappingNode)yaml.Documents[0].RootNode;
var spotifyObjects = new List<Tuple<string, List<Tuple<string,string>>>>();
foreach (var entry in mapping.Children)
{
if (entry.Key.ToString()== "definitions")
{
var classes = (entry.Value as YamlMappingNode).Children.Keys;
foreach (var n in (entry.Value as YamlMappingNode).Children)
{
List <Tuple<string, string>> propertiesTemp = new List<Tuple<string, string>>();
foreach (var cn in (n.Value as YamlMappingNode).Children)
{
if (cn.Key.ToString() == "properties")
{
var properties = (cn.Value as YamlMappingNode).Children.Keys;
Tuple<string, string> temp = null;
foreach (var gcn in (cn.Value as YamlMappingNode).Children)
{
var tempVal = string.Empty;
if ((gcn.Value as YamlMappingNode).Children.Where(c => c.Key.ToString() == "type").Count() > 0)
{
tempVal = (gcn.Value as YamlMappingNode).Children.Where(c => c.Key.ToString() == "type").FirstOrDefault().Value.ToString();
temp = new Tuple<string, string>(gcn.Key.ToString(), tempVal);
propertiesTemp.Add(temp);
}
else if ((gcn.Value as YamlMappingNode).Children.Where(c => c.Key.ToString() == "$ref").Count() > 0)
{
tempVal = (gcn.Value as YamlMappingNode).Children.Where(c => c.Key.ToString() == "$ref").FirstOrDefault().Value.ToString();
tempVal = tempVal.Replace("#/definitions/", "");
tempVal = tempVal.Replace("'", "");
temp = new Tuple<string, string>(gcn.Key.ToString(), tempVal);
propertiesTemp.Add(temp);
}
}
break;
}
}
spotifyObjects.Add(new Tuple<string, List<Tuple<string, string>>>(n.Key.ToString(), propertiesTemp));
}
}
}
result = spotifyObjects.Where(r => r.Item1 == objectName).FirstOrDefault();
return result;
}
tempVal = (gcn.Value as YamlMappingNode).Children.Where(c => c.Key.ToString() == "type").FirstOrDefault().Value.ToString();
temp = new Tuple<string, string>(gcn.Key.ToString(), tempVal);
propertiesTemp.Add(temp);
tempVal = (gcn.Value as YamlMappingNode).Children.Where(c => c.Key.ToString() == "$ref").FirstOrDefault().Value.ToString();
tempVal = tempVal.Replace("#/definitions/", "");
tempVal = tempVal.Replace("'", "");
temp = new Tuple<string, string>(gcn.Key.ToString(), tempVal);
propertiesTemp.Add(temp);
foreach (var gcn in (cn.Value as YamlMappingNode).Children)
How to dynamically create a class?
https://stackoverflow.com/questions/3862226/how-to-dynamically-create-a-class
Configuration:コンストラクタ
public class Configuration
{
IConfigurationRoot config { get; set; }
public string Get(string key,string ver="Current")
public bool Set(string key,string val, string ver =
"Current")
public Configuration()
{
var builder = new ConfigurationBuilder();
builder.AddJsonFile("settings.json");
config = builder.Build();
}
}
Configuration:Get
public string Get(string key,string ver="Current")
{
string result = string.Empty;
if (ver == "Current")
{
result = config.GetSection(key).Value;
}
else
{
var builder = new ConfigurationBuilder();
builder.AddJsonFile("settings" + ver + ".json");
config = builder.Build();
result = config.GetSection(key).Value;
}
return result;
}
Configuration:Set
try
{
if (ver == "Current")
{
config.GetSection(key).Value = val;
}
else
{
var builder = new ConfigurationBuilder();
builder.AddJsonFile("settings" + ver + ".json");
config = builder.Build();
config.GetSection(key).Value = val;
}
result = true;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
settings.json
{
"ClientId": "…",
"ClientSecret": "…",
"AesCryptoServiceProvider Key": "…",
"AesCryptoServiceProvider IV": "…",
"SpotifyYaml": "raw.githubusercontent.com/APIs-guru/openapi-directory/master/APIs/spotify.com/v1/swagger.yaml"
}
https://github.com/APIs-guru/openapi-directory/blob/master/APIs/spotify.com/v1/swagger.yaml
raw.githubusercontent.com/APIs-guru/openapi-directory/master/APIs/spotify.com/v1/swagger.yaml
Encryptor.cs
認証~ユーザー情報を取得する
Microsoft Graph ツールキット
https://docs.microsoft.com/ja-jp/graph/toolkit/overview
認証~ユーザーがログインをクリックした時の動作
認証~認証画面から戻ってきた時の動作
Demo
Spotify Developer Consoleを説明する
Postmanでカレントユーザー情報を取得する
Spotify Web APIにアクセスする
プログラムでカレントユーザー情報を取得する
開発時に使用するデータ(yaml)を参照する
Conclusion
マイクロサービスでは、ドメイン内のデータソースで
完結するソリューションは多くない
サービス経由で情報の授受を行うときはOpen APIな
どに準拠したインターフェイス情報の公開、および受
信の実装が工数軽減につながる
実装の範囲を的確に判断する。必要のないSwagger
UIの実装やクラスの動的生成は本当に必要かどうか要
件を明確にする
Source
Spotify for developers
https://developer.spotify.com/
Postman | API Development Environment
https://www.getpostman.com/
Open API Directory
https://github.com/APIs-guru/openapi-directory
Swagger
https://swagger.io/
Swagger/OpenAPI を使用する ASP.NET Core Web
API のヘルプ ページ
https://docs.microsoft.com/ja-jp/aspnet/core/tutorials/web-api-help-pages-using-
swagger?view=aspnetcore-3.0
Source
YamlDotNet
https://github.com/aaubry/YamlDotNet
How to dynamically create a class?
https://stackoverflow.com/questions/3862226/how-to-dynamically-create-a-class
The Microsoft Graph Toolkit
https://github.com/microsoftgraph/microsoft-graph-toolkit
Getting Started with the Microsoft Graph Toolkit
https://www.youtube.com/watch?v=oZCGb2MMxa0
Sampleソリューション・ソースコード
https://github.com/TetsuroTakao/SpotifyWebAPISample

Contenu connexe

Similaire à Design mvc apps with spotify web api object model

Twitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackTwitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackkimukou_26 Kimukou
 
CSS Nite in Matsuyama vol.1 - session 4
CSS Nite in Matsuyama vol.1 - session 4 CSS Nite in Matsuyama vol.1 - session 4
CSS Nite in Matsuyama vol.1 - session 4 arisu yano
 
ScaLa+Liftとか
ScaLa+LiftとかScaLa+Liftとか
ScaLa+Liftとかyouku
 
cloud_firestore_schema_code_generation_for_flutter.pdf
cloud_firestore_schema_code_generation_for_flutter.pdfcloud_firestore_schema_code_generation_for_flutter.pdf
cloud_firestore_schema_code_generation_for_flutter.pdfKosuke Saigusa
 
Enumはデキる子 ~ case .Success(let value): ~
 Enumはデキる子 ~ case .Success(let value): ~ Enumはデキる子 ~ case .Success(let value): ~
Enumはデキる子 ~ case .Success(let value): ~Takaaki Tanaka
 
Cloud computing competition by Hapyrus
Cloud computing competition by HapyrusCloud computing competition by Hapyrus
Cloud computing competition by HapyrusKoichi Fujikawa
 
初めての Data api cms どうでしょう - 大阪夏の陣
初めての Data api   cms どうでしょう - 大阪夏の陣初めての Data api   cms どうでしょう - 大阪夏の陣
初めての Data api cms どうでしょう - 大阪夏の陣Yuji Takayama
 
Data api workshop at Co-Edo
Data api workshop at Co-EdoData api workshop at Co-Edo
Data api workshop at Co-EdoYuji Takayama
 
OSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニックOSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニック庸介 高橋
 
Html5 Web Applications
Html5  Web ApplicationsHtml5  Web Applications
Html5 Web Applicationstotty jp
 
TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューTypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューAkira Inoue
 
実動するIot&hadoopから学ぶ会_資料
実動するIot&hadoopから学ぶ会_資料実動するIot&hadoopから学ぶ会_資料
実動するIot&hadoopから学ぶ会_資料FwardNetwork
 
バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話
バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話
バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話Masami Yabushita
 
T2 - 関ジャバ1月27日
T2 - 関ジャバ1月27日T2 - 関ジャバ1月27日
T2 - 関ジャバ1月27日Go Tanaka
 
Javaデザインパターン入門【第3回】
Javaデザインパターン入門【第3回】Javaデザインパターン入門【第3回】
Javaデザインパターン入門【第3回】Yukiko Kato
 

Similaire à Design mvc apps with spotify web api object model (20)

Twitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackTwitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hack
 
Rakuten tech conf
Rakuten tech confRakuten tech conf
Rakuten tech conf
 
CSS Nite in Matsuyama vol.1 - session 4
CSS Nite in Matsuyama vol.1 - session 4 CSS Nite in Matsuyama vol.1 - session 4
CSS Nite in Matsuyama vol.1 - session 4
 
ScaLa+Liftとか
ScaLa+LiftとかScaLa+Liftとか
ScaLa+Liftとか
 
cloud_firestore_schema_code_generation_for_flutter.pdf
cloud_firestore_schema_code_generation_for_flutter.pdfcloud_firestore_schema_code_generation_for_flutter.pdf
cloud_firestore_schema_code_generation_for_flutter.pdf
 
jQuery超入門編
jQuery超入門編jQuery超入門編
jQuery超入門編
 
Enumはデキる子 ~ case .Success(let value): ~
 Enumはデキる子 ~ case .Success(let value): ~ Enumはデキる子 ~ case .Success(let value): ~
Enumはデキる子 ~ case .Success(let value): ~
 
Cloud computing competition by Hapyrus
Cloud computing competition by HapyrusCloud computing competition by Hapyrus
Cloud computing competition by Hapyrus
 
初めての Data api cms どうでしょう - 大阪夏の陣
初めての Data api   cms どうでしょう - 大阪夏の陣初めての Data api   cms どうでしょう - 大阪夏の陣
初めての Data api cms どうでしょう - 大阪夏の陣
 
Data api workshop at Co-Edo
Data api workshop at Co-EdoData api workshop at Co-Edo
Data api workshop at Co-Edo
 
OSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニックOSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニック
 
Ajax 応用
Ajax 応用Ajax 応用
Ajax 応用
 
Html5 Web Applications
Html5  Web ApplicationsHtml5  Web Applications
Html5 Web Applications
 
20071030
2007103020071030
20071030
 
TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューTypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービュー
 
実動するIot&hadoopから学ぶ会_資料
実動するIot&hadoopから学ぶ会_資料実動するIot&hadoopから学ぶ会_資料
実動するIot&hadoopから学ぶ会_資料
 
バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話
バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話
バッテリー監視のためにバックグラウンドタスクについて調べたらなくなってたから泣く泣くタイマーApiを使ってみた話
 
Teclab3
Teclab3Teclab3
Teclab3
 
T2 - 関ジャバ1月27日
T2 - 関ジャバ1月27日T2 - 関ジャバ1月27日
T2 - 関ジャバ1月27日
 
Javaデザインパターン入門【第3回】
Javaデザインパターン入門【第3回】Javaデザインパターン入門【第3回】
Javaデザインパターン入門【第3回】
 

Plus de Takao Tetsuro

Small Language Model Local Launch on AI Tour Tokyo
Small Language Model Local Launch on AI Tour TokyoSmall Language Model Local Launch on AI Tour Tokyo
Small Language Model Local Launch on AI Tour TokyoTakao Tetsuro
 
local launch small language model of AI.
local launch small language model of AI.local launch small language model of AI.
local launch small language model of AI.Takao Tetsuro
 
Implementation Approach of Artifical Intelligence
Implementation Approach of Artifical IntelligenceImplementation Approach of Artifical Intelligence
Implementation Approach of Artifical IntelligenceTakao Tetsuro
 
MAUIGraphicsNamespace.pptx
MAUIGraphicsNamespace.pptxMAUIGraphicsNamespace.pptx
MAUIGraphicsNamespace.pptxTakao Tetsuro
 
Polyglot Persistence and Graph Schema
Polyglot Persistence and Graph SchemaPolyglot Persistence and Graph Schema
Polyglot Persistence and Graph SchemaTakao Tetsuro
 
ServiceMeshEndpointWithMinimalAPIPublish.pptx
ServiceMeshEndpointWithMinimalAPIPublish.pptxServiceMeshEndpointWithMinimalAPIPublish.pptx
ServiceMeshEndpointWithMinimalAPIPublish.pptxTakao Tetsuro
 
OptonsPatternDotNet.pptx
OptonsPatternDotNet.pptxOptonsPatternDotNet.pptx
OptonsPatternDotNet.pptxTakao Tetsuro
 
ASP.NETCoreOptionsPattern.pptx
ASP.NETCoreOptionsPattern.pptxASP.NETCoreOptionsPattern.pptx
ASP.NETCoreOptionsPattern.pptxTakao Tetsuro
 
Layout isfirstprocessofatomicdesign
Layout isfirstprocessofatomicdesignLayout isfirstprocessofatomicdesign
Layout isfirstprocessofatomicdesignTakao Tetsuro
 
Wasm blazor and wasi 2
Wasm blazor and wasi 2Wasm blazor and wasi 2
Wasm blazor and wasi 2Takao Tetsuro
 
WebAssemblyとBlazor 、WebAssembly System Interfaceでコンテナライズの設計を解説
WebAssemblyとBlazor 、WebAssembly System Interfaceでコンテナライズの設計を解説WebAssemblyとBlazor 、WebAssembly System Interfaceでコンテナライズの設計を解説
WebAssemblyとBlazor 、WebAssembly System Interfaceでコンテナライズの設計を解説Takao Tetsuro
 
Interoperability of webassembly with javascript
Interoperability of webassembly with javascriptInteroperability of webassembly with javascript
Interoperability of webassembly with javascriptTakao Tetsuro
 
Interactive connection2
Interactive connection2Interactive connection2
Interactive connection2Takao Tetsuro
 
Relationship betweenddd and mvc
Relationship betweenddd and mvcRelationship betweenddd and mvc
Relationship betweenddd and mvcTakao Tetsuro
 
M365VM_PowerFX_takao-matsumoto_matsui_kojima
M365VM_PowerFX_takao-matsumoto_matsui_kojimaM365VM_PowerFX_takao-matsumoto_matsui_kojima
M365VM_PowerFX_takao-matsumoto_matsui_kojimaTakao Tetsuro
 
OpenStreetMap and Mapbox
OpenStreetMap and MapboxOpenStreetMap and Mapbox
OpenStreetMap and MapboxTakao Tetsuro
 
Excel on OneDrive is not a file
Excel on OneDrive is not a fileExcel on OneDrive is not a file
Excel on OneDrive is not a fileTakao Tetsuro
 
Development toolsforteamdevelopment
Development toolsforteamdevelopmentDevelopment toolsforteamdevelopment
Development toolsforteamdevelopmentTakao Tetsuro
 

Plus de Takao Tetsuro (20)

Small Language Model Local Launch on AI Tour Tokyo
Small Language Model Local Launch on AI Tour TokyoSmall Language Model Local Launch on AI Tour Tokyo
Small Language Model Local Launch on AI Tour Tokyo
 
local launch small language model of AI.
local launch small language model of AI.local launch small language model of AI.
local launch small language model of AI.
 
Implementation Approach of Artifical Intelligence
Implementation Approach of Artifical IntelligenceImplementation Approach of Artifical Intelligence
Implementation Approach of Artifical Intelligence
 
MAUIGraphicsNamespace.pptx
MAUIGraphicsNamespace.pptxMAUIGraphicsNamespace.pptx
MAUIGraphicsNamespace.pptx
 
Polyglot Persistence and Graph Schema
Polyglot Persistence and Graph SchemaPolyglot Persistence and Graph Schema
Polyglot Persistence and Graph Schema
 
ServiceMeshEndpointWithMinimalAPIPublish.pptx
ServiceMeshEndpointWithMinimalAPIPublish.pptxServiceMeshEndpointWithMinimalAPIPublish.pptx
ServiceMeshEndpointWithMinimalAPIPublish.pptx
 
OptonsPatternDotNet.pptx
OptonsPatternDotNet.pptxOptonsPatternDotNet.pptx
OptonsPatternDotNet.pptx
 
ASP.NETCoreOptionsPattern.pptx
ASP.NETCoreOptionsPattern.pptxASP.NETCoreOptionsPattern.pptx
ASP.NETCoreOptionsPattern.pptx
 
gRPCurlDotNet.pptx
gRPCurlDotNet.pptxgRPCurlDotNet.pptx
gRPCurlDotNet.pptx
 
Layout isfirstprocessofatomicdesign
Layout isfirstprocessofatomicdesignLayout isfirstprocessofatomicdesign
Layout isfirstprocessofatomicdesign
 
Wasm blazor and wasi 2
Wasm blazor and wasi 2Wasm blazor and wasi 2
Wasm blazor and wasi 2
 
WebAssemblyとBlazor 、WebAssembly System Interfaceでコンテナライズの設計を解説
WebAssemblyとBlazor 、WebAssembly System Interfaceでコンテナライズの設計を解説WebAssemblyとBlazor 、WebAssembly System Interfaceでコンテナライズの設計を解説
WebAssemblyとBlazor 、WebAssembly System Interfaceでコンテナライズの設計を解説
 
Team development
Team developmentTeam development
Team development
 
Interoperability of webassembly with javascript
Interoperability of webassembly with javascriptInteroperability of webassembly with javascript
Interoperability of webassembly with javascript
 
Interactive connection2
Interactive connection2Interactive connection2
Interactive connection2
 
Relationship betweenddd and mvc
Relationship betweenddd and mvcRelationship betweenddd and mvc
Relationship betweenddd and mvc
 
M365VM_PowerFX_takao-matsumoto_matsui_kojima
M365VM_PowerFX_takao-matsumoto_matsui_kojimaM365VM_PowerFX_takao-matsumoto_matsui_kojima
M365VM_PowerFX_takao-matsumoto_matsui_kojima
 
OpenStreetMap and Mapbox
OpenStreetMap and MapboxOpenStreetMap and Mapbox
OpenStreetMap and Mapbox
 
Excel on OneDrive is not a file
Excel on OneDrive is not a fileExcel on OneDrive is not a file
Excel on OneDrive is not a file
 
Development toolsforteamdevelopment
Development toolsforteamdevelopmentDevelopment toolsforteamdevelopment
Development toolsforteamdevelopment
 

Dernier

Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 

Dernier (9)

Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 

Design mvc apps with spotify web api object model

Notes de l'éditeur

  1. 今回のセッションではMVCの設計のお話です。MVCの設計のお話は今さらな感じはしますが、マイクロサービスをMVCデザインパターンで設計する際に、マッシュアップしたWeb APIのモデリングや、ファサードから永続化層のスキーマとしてO/Rマップを明解に解決する手法など、MVCを再学習したいと思い今回のセッションを行うことにしました。 まず、第一弾としてWeb API編をお話しします。次回、永続化編にてマイクロサービスの永続化、Key-Value storeへの永続化のお話しをします。 【クリック】
  2. 自己紹介をよむ 【クリック】
  3. 読む【クリック】 マイクロサービスは、今やシステム開発の選択肢として大きな位置を占めていると感じています。以前.NETラボでお話ししたように、マイクロサービスは個々のマイクロサービスがそれぞれの永続化層を持ち、ステートフルなミドルウェアを構築するように設計(リライアブル・アクターをデザイン)することで、スケーラブルや高パフォーマンスといった分散アーキテクチャの利点を最大限に引き出すことが可能になり、かつアジャイルにシステムを開発することができます。 一方、MVCデザインパターンは様々なシステム開発で長く採用され、周辺ツールの多さ、ソース管理のしやすさなどの利点に加え、開発者がソースコードの構成を一見して把握できるほどに新規メンバーのプロジェクト参加の学習コストが低いのもアジャイルなシステム開発を後押ししています。 マイクロサービスをMVCデザインパターンで設計する場合、業務の問題を解決するために比較的大きなオブジェクトモデルが必要であり、個々のマイクロサービスはその一部のモデルを扱うことになります。 ここで重要なことは、ステートフルなミドルウェア上でこれらのモデルを結合していく必要があるということです。【クリック】
  4. マイクロサービスをMVCデザインパターンで設計する一例として、サンプルのシナリオを説明します。 ファサードを経由してシステム内に入ってくるデータは各マイクロ・サービス内でモデル化します。業務の問題解決を行う比較的大きなオブジェクト・モデルに直接データを入れるとそのオブジェクトはミドルウェアに居座ることになり、永続化層をステートマシンにしているのと何ら変わりありません。 ステートフル・ミドルウェアをアクター・パターンでインプリメントしている場合は、個々のモデルに投入されたデータはそのライフサイクルによって必要に応じてアクターが永続化します。アクターの生存期間中はインメモリで展開されます。 マイクロサービスをMVCデザインパターンで設計するというのは、複数のマイクロサービスによって生成されるモデルを合成して、業務の問題解決のオブジェクトモデルを構築するスキームを作るということです。【クリック】
  5. サンプルとして取り上げるのはSpotifyのWeb APIが提供するObject Modelです。 音楽を表現するモデルが用意されています。 【クリック】
  6. Web APIはjsonで返ってきますので、受け取ったデータはモデルにマップして操作します。 Web APIはOAuthで認証して使いますので、最初にユーザー情報を取得することになります。 そのため、コードはこんな感じになります。最初に必要なことは、この「SpotifyUser」というクラスを作ることです。 【クリック】
  7. 「SpotifyUser」クラスは、先ほどのSpotify Web API Object Modelのページを参照して、このように作ってもいいのですが、タイプリゾルバを作るとコーディングが楽になります。 【クリック】
  8. タイプリゾルバは、Web API側がどのようなインターフェイスを用意しているかを公開する構成にすることで、APIのインターフェイスの更新時でも継続的インテグレーションを実現します。 Spotify Web API Object Modelは、Open APIに準拠しており、Swaggerのyamlを公開しています。 【クリック】
  9. このファイルを使用することでタイプリゾルバを簡単に作成することができます。【クリック】
  10. Web APIのインターフェイスの記述をするためのOpen APIの標準フォーマットがSwaggerで、Swagger UIはインターフェイスを定義したyamlからHTMLを自動生成してくれるのでSwagger Editorでyamlを生成、編集したりSwagger Codegenでコードを自動生成したりすることでWeb APIの提供元は保守、運用作業が楽になります。 これらのツールはjavaを使ってインプリしたりするので、Spotity Web APIの利用者として、Object Modelのタイプリゾルバを作るだけならyamlを読み込む機能を実装するだけで十分です。 また、Swaggerを装備したWeb APIを.Netで構築することもできます。
  11. Web APIを提供する場合は実装することをお勧めします。
  12. Spotify Web APIのObject Modelのタイプリゾルバを作る方法として、yamlを読み込む機能を実装します。
  13. YamlDotNetをNuGetからインストールします。
  14. Tuple<string, List<Tuple<string, string>>>でクラス名、プロパティ名、プロパティの型を表しています。Albumなどの引数で、そのクラスを返すようにしています。 Configurationは後述しますが、認証時のIDやyamlのアドレスを外だししています。 読み込んだテキストをインストールしたYamlDotNetの機能を使ってLoadしています。 最後にChildノードをYamlMappingNodeキャストしてスキャンしています。Open APIの仕様では「definitions」でオブジェクトを定義して「properties」でオブジェクトのメンバーを定義することになっており、「type」でデータの型を定義します。
  15. 「properties」で取得するオブジェクトのメンバーのうち「type」でデータの型を定義していないものは、オブジェクトを参照しています。
  16. サンプルのクラスは、Tuple<string, List<Tuple<string, string>>>という型で返しています。実際にオブジェクトモデルにしたい場合はSystem.Reflectionを使って動的に完全なクラスを作ることができます。 ただし、クラス名、プロパティ名、プロパティの型が管理できればViewにオブジェクトモデルを表現することができます。Web APIに入力する必要が無く、シリアライズされて転送されてくるデータを利用するのであれば、string型とタプル、リストを組み合わせた型でデシリアライズすることができます。
  17. サンプルのクラスは、Tuple<string, List<Tuple<string, string>>>という型で返しています。実際にオブジェクトモデルにしたい場合はSystem.Reflectionを使って動的に完全なクラスを作ることができます。 ただし、クラス名、プロパティ名、プロパティの型が管理できればViewにオブジェクトモデルを表現することができます。Web APIに入力する必要が無く、シリアライズされて転送されてくるデータを利用するのであれば、string型とタプル、リストを組み合わせた型でデシリアライズすることができます。
  18. 上の2つのライブラリは後述しますが、NetCore21Utilitiesライブラリしか使ってません。この中に先ほどのConfigやEncryptor、Resolverなどが入っています。 流れを説明すると、ASP.NET Core 2.1のアプリケーションがあり、HomeコントローラーのIndexアクションで処理を行っています。 まず初期表示ではindex.chtmlが表示され、ログインをクリックすると認証を行ってユーザーの名前が表示されるという仕組みです。この仕組みはHomeコントローラーのIndexアクションに再帰するようにしています。多くのOAuth対応のWeb APIはSDKが用意されていますのでMicrosoft GraphのようにSpotify Web APIにも用意されています。これらのSDKの使い方はインターネット上にたくさんあるのでそちらを参照してください。ここでは上級者向けにstateの検証などOAuthのステップ制御を行っています。 ログインがクリックされたらIndexアクションの変数「signin」に「true」が渡されます。その値を判別して初期表示とログイン表示を切り替えています。 認証を行って帰ってきたら「Request.Query」に値が入ります。TryGetValue(“state”, out stateText)でstateを抜き取り、認証直前に「TempData」に仕込んだ値と照合して、ユーザー情報を取得するようにしています。