Morning Girl

Web API, Windows, C#, .NET, Dynamics 365/CRM etc..

2019年の活動棚卸しと2020年の方針をまとめてみる

あけましておめでとうございます!

去年に引き続き2019年も活動の棚卸しと2020年の方針をまとめてみようと思います。

kageura.hatenadiary.jp

ちなみに、去年はちょっと手軽にExcelで済ませてしまったので、今回はしっかりとPowerBIでやってみました。

2019年の棚卸し

Blogの状況

一応私は自分自身のBlogと会社のBlogの両方で記事を投稿しているのですが、とりあえずメインのMorningGirlの投稿状況を見てみます。

去年は43件とちょっと少なめとなったのですが、今年は51件と2015年に次ぐ件数となり、結構精力的にBlog活動ができました。ただ、月別の投稿件数を見ると1月が14件と圧倒的なのに、それ以降が伸び悩み。

f:id:sugimomoto:20200103155713p:plain

カテゴリはAPIが2018年と変わらないですが、ZOZO前澤社長のツイート収集などをしたことや、JJUGでの登壇をまとめた記事を書いたことなどもあって、TwitterJavaのコンテンツが増えていることがわかります。

あとは意外とDynamicsに関する発信もしていたなと思ったり。PowerBIの方が多いかなというイメージでしたが。

PVベースでは前年比意外と伸び悩み。14%増に留まりました。人気記事の傾向を見ると、2018年に投稿したRESTとはなんぞや、MongoDBやRedisの事始め記事が強いのがよくわかります。このあたりは確かにあまり書いてなかったなぁと思ったり。

f:id:sugimomoto:20200103155722p:plain

ちなみに今年一番はてなブックマークがついた記事は「無料の API 自動生成ツールを使って、Excelファイルから REST API を生成してみる:CData API Server」でした。199ブクマ。

kageura.hatenadiary.jp

タイトル的に伸びるかなと思っていましたが、想定以上に大きな反響があってよかったです。

次にブックマークが多かったのは「500万件を超えるTwitterリツイート データを取得・分析する方法 -Twitter Premium Search API を実際に使ってみてわかった嵌りポイントとその対策-」

かなり挑戦的な取り組みだったと個人的にも思っていたので、よかったなーと思っています。

bit.ly

  • 会社のBlog

ちなみに、会社のBlogには「33件」投稿していました。自分のBlogと併せてトール「84件」だったので、来年は100を目指してもいいかもですね。

www.cdatablog.jp

SNSTwitter

Blogは伸び率がそこまででもありませんでしたが、ツイッターは結構頑張っていたみたいでした。ツイート数だけでも、去年の2倍くらい。そこまで意識していたわけでも無いので意外でした。

f:id:sugimomoto:20200103155732p:plain

ただ、後述の勉強会への参加数が大きく伸びていたので、それに伴うツイート数の増加が大きな要因ではないかなと見ています。

あと、APIに関するツイート数が1000を超えていたのはいいですね。関連のニュース・トピックに関しては積極的に発信していくようにしましたが、去年に比べて3倍の発信量でした。

勉強会・コミュニティ

個人的に一番大きく変わったなーと思ったのは、勉強会・コミュニティに対する参加・登壇状況でした。

2018年が22参加でそれでも結構多いなと思っていたのですが、2019年は36個になっていました。

プラス、それよりも登壇数の大幅増加が凄まじい。2018年5個だったのに、2019年が19と3倍強に。

f:id:sugimomoto:20200103155742p:plain

もうちょっとちまちまLTをしているのかなと思いきや、実はメイン登壇がほとんどで、そこもまたびっくり。

ちなみに表には出していないのですが、主催イベントも合計5個と、よくやったなーと改めて思います。

なお、仕事の登壇も「3件」ほどあったので、トータル「22件」発表していたようです。

Youtube

途中からやり始めたYoutubeは合計5つとまだまだこれから感。

基本的にイベントの登壇を編集して公開しているだけだったので、視聴数的にもこんな感じかなというところに留まりました。

f:id:sugimomoto:20200103155750p:plain

イベントの配信は2回ほど行いましたが、GoProでの配信はそれなりによかった感です。

来年はもう少し仕事としてもうまく活用していきたいと思っています。

API

今年もいろんなAPIを触って、CData Driverとコラボレーションしていきました。

いくつか公開している、CData Driverでのプロトタイプは公開していないものも含めてトータル20個近く作ったみたいでした。

公開しているメインどころは以下のようなサービスです。

PostmanのAPI検証を行ったコレクションもトータル49個と多くなっています。2018年からの差分は取っていないので、このあたりは来年の伸び率もウォッチしていきたいところですね。

2020年に向けて

Blog

Blogの投稿はイベントへの参加と併せてもうちょっと伸ばしたいところです。登壇をスライドで済ますだけでなく、記事にもしておくサイクルが2019年は確立できたかなーというところなので、そこは引き続き同じ用に注力。

API検証記事+反響が良かったAPI公開記事を別データソースや別シナリオ・クライアントとのコラボレーションで増やして、トータル60くらいを目指せればというところでしょうか。

コミュニティ

登壇は引き続き頑張っていきたいところですが、量的には今の数くらいがやれる範囲かなとも思ったりです。

それよりも、BlogやSNSYoutubeによるアウトプットの質を高めて行く感じかなとも考えていたりですね。

SNSTwitter

Twitter の投稿は今まで通り、API注力で。もう少しシナリオペインで、発信していきたいところ。そこまで2019年で意識してツイートしていたわけでも無いので、API検証と併せて1500ぐらいは目指せるんじゃないかなと思ったりです。

Youtube

Youtubeはもうちょっとちゃんとやろうと思ったりでした。

今までは勉強会での登壇を記録したものベースでしたが、そもそも勉強会やイベント登壇前にランスルーをするので、それをYoutube用にキレイに編集して公開していきたいなと考えています。

トータル12本(月1)くらいかなー。

API

個人的に今年一番注力したいのはここですね。

存在を知っていながらも、まだ API 検証が済んでいないものは以下の通りかなーと。このあたりを引き続きCDataも含めてコラボレーションしていきたいところなので、2019年は20件でしたが、2020年は40件ほどを目標にしていく心づもりです。

その他

Blazor の取り組みは個人的に大きなターニングポイントでした。今まで個人としてWebサービス・アプリを公開したことが無かったんですが、私自身が持っているスキルをうまく活用しながら公開できることもあり、この辺を組み合わせて何か面白いアプリを作って、公開していければなと。

kageura.hatenadiary.jp

VS Code Snippet も私が今までやっていたものとは大きく違った取り組みでした。拡張機能開発にも興味があるので、会社の製品とも組み合わせて何か公開できればとも画策したり。

kageura.hatenadiary.jp

Dynamics + PowerPlatformは、社内でCDSを使おうかなーとも考えていることもあり、APIと組み合わせた取り組みを発信していければなと考えています。

Blazor で API Explorer を作って色々悩んだお話 #GyutanKaigi2019

先週土曜日に仙台で開催した「牛タン会議2019」でBlazorについての発表をしてきました! 今回はその内容をもうちょっとまとめて、Blogとして公開したものになります。

speakerdeck.com

vsuc.connpass.com

ちなみに、この記事は Blazor アドベントカレンダー 12日目です。めちゃくちゃ遅くなってごめんなさい・・・orz

qiita.com

こんなものを作ってみた

実は私、ちょうど2ヶ月ほど前から Blazor を触り始めたんですが、なんて素晴らしい!  JavaScriptフレームワークが苦手な私でもこれならなんか作って公開できそうだ!(思い違い) と感激していました。

そこで、当時開発でよく悩んでいたスマレジのAPIを手軽に実行できるアプリを作ってみたのです。

f:id:sugimomoto:20191217212509p:plain

スマレジ API はすごく柔軟な機能を提供していて、数多くの操作、リソースをコントロールできるのですが

f:id:sugimomoto:20191217212518p:plain

API リクエストの仕様がちょっと独特かつ、項目が多いので気軽に試すのが難しいかなーというAPIでした。

f:id:sugimomoto:20191217212525p:plain

なので、FacebookMicrosoft が公開しているような API Explorer を作って公開しちゃえば、このつらみから開放されるのではないか!? と考えたのです。

そして作ってみたのがこんな感じのものです。

https://cdatajbuilds.s3-ap-northeast-1.amazonaws.com/sugimototest/smaregi.gif

まだ手直し真っ只中ですが、以下のAzure Web Apps で公開しています。(低料金プランとSignalIR未設定のためか、ちょっと重い・・・)

https://smaregiapiexplorer.azurewebsites.net/

さて、なんとか自分がイメージしていたものが動くところまでは至ったのですが、そこで色々とぶつかっていたので、それを共有したいと思います。

私が遭遇した課題 その1

このAPI Explorer を実装する上で、一番の課題だったところは、一番の機能的ポイントでもある、動的なテーブル形式のInputフォームでした。

f:id:sugimomoto:20191217212534p:plain

スマレジ APIは各カラムのフィルターを柔軟に書けるようになっている反面、この部分のリクエストをJSONで書くのがなかなか大変だったので、この部分の実現が一番の肝でした。

ただ、この動的なInputフォーム動的であるが故に、Blazorの強力なバインディング機能でプロパティに値をバインディングできない(できないよね? できたら教えて下さい)!

バインディングできないと、値のとり方がわかんない!

私の試みた解決策 その1

まあ、しょうがない。それじゃあDOM APIにアクセスして、動的に取ってくればいいんでしょ? と考えたので Blazor で DOM APIにアクセスするライブラリはなーんだ? と探したわけですが

FAQ · aspnet/Blazor Wiki · GitHub

Q: Can I access the DOM from a Blazor app?

You can access the DOM through JavaScript interop from .NET code. However, Blazor is a component based framework that minimizes the need to access the DOM directly.

(あなたはBlazor で DOM にアクセスできるよ! そう、JavaScript ならね!:意訳)

JavaScriptか・・・!

Blazor では JavaScript 相互運用機能(Interop)という、.NET MethodからJavaScriptを呼び出す機能が備わっており、この機能でJavaScriptが取得したDOM APIのデータをJSONなどの形式にまとめて、レスポンスとして .NET 側に返す機能が備わっています。

docs.microsoft.com

できる限り、JavaScriptを書きたくなかった私ですが、ここで諦めてHTMLテーブルのInputをなめて、JSONを返すJavaScriptMethodを書き、対応することにしました。

私が遭遇した課題 その2

しかし、ここでも躓きます。JavaScriptでDOM APIにアクセスして、テーブルの情報を取得することはできました。

ただ、Blazorは各Inputやバインディングの値が変更された際に、DOM要素をレンダリングし直します。

docs.microsoft.com

その結果、JavaScript 相互運用で非同期処理をしていることにより、リクエスト生成ボタンをクリックする(JavaScript が DOM の値を取得する)前に、Blazor が DOMを初期状態に書き換えてしまい、値が取得できないということが発生。

取得できていても非同期処理がレンダリングのタイミングがずれて、裏の変数では値を保持しているのに、レンダリングしている値と一致しないということまで発生しました。

私の試みた解決策 その2

結局私が最終的に試みたアプローチは、テーブルInputが変更される度に JavaScriptで値を取得して、テーブルを構成するためのListプロパティに逐次差し戻し、最新化するというものでした。

以下の「columnInput」がテーブルを構成するための要素をすべて保持しており、

                <BSTable IsSmall="true" IsBordered="true" IsStriped="true" Class="overflow-auto" style="max-height: 200px;">
                    <BSTableHead>
                        <BSTableRow>
                            <BSTableHeadCell>Select</BSTableHeadCell>
                            <BSTableHeadCell>Id</BSTableHeadCell>
                            <BSTableHeadCell>ColumnName</BSTableHeadCell>
                            <BSTableHeadCell>ColumnName(J)</BSTableHeadCell>
                            <BSTableHeadCell>ColumnType</BSTableHeadCell>
                            <BSTableHeadCell>ConditionType</BSTableHeadCell>
                            <BSTableHeadCell>ConditionValue</BSTableHeadCell>
                            <BSTableHeadCell>Description</BSTableHeadCell>
                        </BSTableRow>
                    </BSTableHead>
                    <BSTableBody>
                        @foreach (var column in columnInput)
                            {
                        <BSTableRow>
                            <BSTableCell>
                                <BSBasicInput Class="form-control-sm" InputType="InputType.Checkbox" Value="@column.Select"></BSBasicInput>
                            </BSTableCell>
                            <BSTableCell>@column.No</BSTableCell>
                            <BSTableCell>@column.Name</BSTableCell>
                            <BSTableCell>@column.JapaneseLabel</BSTableCell>
                            <BSTableCell>@column.Type</BSTableCell>
                            <BSTableCell>
                                <BSBasicInput Class="form-control-sm" InputType="InputType.Select" Value="@column.ConditionType" @onselect="@SetColumnInput">
                                    <option></option>
                                    <option>=</option>
                                    <option>like</option>
                                    <option>&lt;</option>
                                    <option>&lt;=</option>
                                    <option>&gt;</option>
                                    <option>&gt;=</option>
                                </BSBasicInput>
                            </BSTableCell>
                            <BSTableCell><BSBasicInput Class="form-control-sm" InputType="InputType.Text" Value="@column.ConditionValue" @onchange="@SetColumnInput"></BSBasicInput></BSTableCell>
                            <BSTableCell>@column.Description</BSTableCell>
                        </BSTableRow>
                            }

                        @if (columnInput.Count == 0)
                            {
                        <tr>
                            <td colspan="8">No Records</td>
                        </tr>
                            }
                    </BSTableBody>

                </BSTable>

SelectボックスなどのInputが操作されるたびに、JavaScriptが値を取り直しています。

        public async void SetColumnInput()
        {
            columnInput = await JSRuntime.InvokeAsync<List<ColumnInput>>("tableDataManager.getTableValues");
        }

これにより、テーブルを構成しているオブジェクトの値を最新に保つようにしています。

Blazor でアプリを作る上で感じたポイント

と、ここまで私の課題と解決アプローチをお話してきたのですが、これが「まっとうな」「ベスト」といえるアプローチに行き着くことができていない、というのが正直なところです。

なので、この発表をした牛タン会議では、最終的に会場に居る素晴らしいMS MVP の方々へ「どうしたらよかっただろう?」というのを聞く! というが本来の目的だったのですが

f:id:sugimomoto:20191217212547p:plain

ちょっと会場の時間が押していたこともあり、なくなく断念となりました(泣

というわけで、せっかくなので、このBlogでもヒドイコードを晒して対応アプローチを募ってみたい、と思っています。

github.com

ちなみに、私がこの経験を通じて得た教訓は「できる限り値はバインディングするに限る。直接的なバインディングなのか、間接的なバインディングに問わず」というものでした。

(こんなBlogでいいのだろうか。)

おしまい

MuleSoft AnyPoint Studio で kintone をデータソースとした Customer アプリ参照APIを作成する:CData kintone MuleSoft Connector

この記事は MuleSoft Advent Calendar 2019 の9日目の記事として投稿しています。

qiita.com

今回この記事では、CData Software で提供しているkintone をデータソースとして、kintone の顧客管理用のアプリを抽象化したAPIを作成してみようと思います。

f:id:sugimomoto:20191209203429p:plain

  • そもそもなぜ抽象化したAPIを作成するのか?
  • kintone Cusomter API の作り方
  • kintone MuleSoft Connector のダウンロード・セットアップ
    • API定義の作成
    • AnyPoint Studio の準備
    • Cusomter APIの処理を実装する
  • おわりに
続きを読む

ASP.NET Core Blazor C# で CData ADO.NET Provider kintone を使う

f:id:sugimomoto:20191129194451p:plain

最近 Blazor を触り始めました!

JavaScriptフレームワークjQueryで止まっている私(Reactはちょこっと触ったけど)にはめちゃくちゃありがたいフレームワークだなと思いながら、楽しんでいます。

Blazorは .NET ライブラリ・既存の .NET エコシステムを流用できるのが大きなポイントです。やっぱり JSON.NET とか REST Clientとか使いたい。

docs.microsoft.com

そして、私の会社で提供している CData ADO.NET Provider も .NET Core 対応をしていたので、これならイケそうじゃん? と思い、試してみました。

続きを読む

Dynamics 365 Business Central のトライアル取得方法と API の使い方

Dynamics 365 Business Central のトライアルは個人的に何回か取得しているんですが、かなり毎回勘所を忘れてしまうので、書き残しておきたいと思います。

また、ざっとAPIを使うための下地も見えたので、OAuthやAzureADへの登録などのあたりも併せて。

続きを読む

ADO.NET ORM の Dapper で CData ADO.NET Provider の使い方

最近 Sansan の中の人のBlogで「今までEntityFrameworksとDapperを使っていたけれど、軽量なDapperを全面的に採用しました」というのを見かけました。

buildersbox.corp-sansan.com

私自身が今まで Dapper を使ったことが無かったので、どんな感じなのかな? という点と、ADO.NET ベースなら、CData ADO.NET Providerも動くでしょ! と思ったので、検証してみた結果をまとめてみたいと思います。

続きを読む

独自スクリプト言語の VS Code Snippet を作ってみた:CData API Script

普段メインのエディタとして、VS Codeを使っています。

簡単なプログラミングから、ログ漁り、PowerShellなどの実行まで、これで一通りやっているんですが、その中の一つに私の会社で出している製品の独自スクリプト言語を書くという仕事(半分趣味)がありました。

こんな感じでXMLを拡張して、製品に独自の拡張機能をもたらす感じのもので、CData API Script と言います。

f:id:sugimomoto:20191029224204p:plain

続きを読む