狛ログ

2020年12月30日水曜日

Spring Fest 2020に参加しました。

12月 30, 2020

オフィス狛 技術部のJoeです。

Spring Fest 2020が開催されましたので、昨年に引き続き参加しました。
公式ページ

今年はオンライン開催ということで、昨年のような雰囲気ではありませんでしたが、
質問をチャットで受け付けてセッション後に回答いただけるなど、良かった点もありました。

また、今回は「Advanced Track」と「Beginner track」の2トラックで分かれて配信されていましたので、初めて参加される方も、セッションを選択し易かったかと思います。
(私はどれも聞いてみたく、結構直前まで迷ってしまいました)

今回も、特に気になったセッションの感想を、ブログに残したいと思います。


今こそ知りたいSpringエコシステム

槙 俊明さん(VMWare)
セッション資料

Springの歴史から始まり、主なSpring Projectを下記の3つの分類に分けて紹介されていました。
・できることを増やす
・バリエーションを増やす
・使いやすくするプロジェクト

改めて、様々なプロジェクトがあることを認識させられたことと、
最新情報は、書籍ではなく、公式ドキュメントと
プロジェクト開発者のGihub、Twitterで集めることが勉強になりました。


今こそ知りたいSpring DI × AOP

多田 真敏さん(株式会社カサレアル)
セッション資料

Springの基礎である、コンテナ、DI、スコープ、プロキシ、AOPについて丁寧に解説されていました。
初心者向けとありましたが、私の勉強不足もあり、なかなか説明に追いつけないところがありましたので、是非、もう一度復習したい内容でした。


CloudNativeな決済サービスの開発と2年間の歩み

鈴木 順也さん(SBペイメントサービス)
セッション資料

大規模な決済サービスのシステムを、2年間運用された実績をもとに、
アプリケーション構成とアプリの役割から、
ライブラリの移行と発生した問題、開発体制、CI / CD、テスト、Observabilityといった内容を
実績で紹介されていました。

1つのサービスの歩みという内容がとても面白く、勉強になりました。
また、2年経過してシステム数やアプリ数が増加しているのでに、
プラットフォーム運用者はほぼ変わらないという点にはとても驚きました。


Spring 5.3 & Spring Boot 2.4

槙 俊明さん(VMWare)
セッション資料

こちらはSpring 5.3 と Spring Boot 2.4 の新機能の紹介でした。
常に新しいもの、いいものを取り込んで進化しているという印象を受けました。

特に気になったのは、「プロパティ読み込み方法の改善」で、YAMLの定義方法が紹介されていました。
過去にSpring Boot のバージョンアップを行った際に、YAMLの定義方法の変更で、
結構ハマってしまうことがあったので、早めのバージョンアップが必要だなと思いました。

またこちらのセッション後にあった、Springについて色々な観点からの質問コーナー(?)は個人的に面白かったです。



今回はオンラインでの開催で、目的のセッションをゆっくり視聴できました。

今回のセッション動画は、今は非公開になっていますが、
来年に公開される予定とのことですので、今回視聴出来なかったセッションも確認してみたいと思います。


node.jsでS3上の画像ファイルをPDFファイルに変換する方法。

12月 30, 2020

オフィス狛 技術部のJoeです。

担当したプロジェクトで、S3上の画像ファイルをPDFファイルに変換する要件がありましたので、
変換方法を備忘も兼ねてご紹介しようと思います。

今回使用したライブライは2つです。 ※()は使用したバージョンです
・pdf-lib(1.11.1):PDFファイルを編集するためのnpmパッケージ
・sharp(0.26.3):画像ファイルを編集するためのnpmパッケージ


1.S3上の画像ファイル読み込む

S3から画像ファイルを読み込んで、bufferデータを取得します。
ここで問題になったのは、読み込んだ画像ファイルが意図せずに回転してしまったことです。
読み込んだ画像ファイルの回転情報を保持するために、sharpのライブラリを使用しました。

const aws = require('aws-sdk');
const sharp = require('sharp');

// S3にアクセスするための情報
const s3Client = new aws.S3({
  accessKeyId: [S3アクセスキー],
  secretAccessKey: [S3シークレットアクセスキー],
  region: [S3のリージョン],
});

const params = {
  Bucket: [S3バケット名],
  Key: [S3ファイルパス/ファイル名],
};

// S3の画像ファイルを取得
dataInS3 = await s3Client.getObject(params).promise();

// 画像ファイルのbufferデータを取得(rotateの引数なしで、読み込んだ画像の回転情報を保持する)
bufferData = await sharp(dataInS3.Body).rotate().toBuffer();

2.pdf-libで画像をPDFファイルに埋め込む

読み込んだ画像ファイルをPDFファイルに埋め込みます。
この処理では、読み込んだ画像ファイル容量が大きい場合、メモリ使用率にご注意ください。

const { PDFDocument } = require('pdf-lib');

// 空のPDFを作成
const pdfDoc = await PDFDocument.create();

// 画像のbufferデータをPDFに埋め込む
image = await pdfDoc.embedJpg(bufferData);  // jpgファイルの場合はこちら
image = await pdfDoc.embedPng(bufferData);  // pngファイルの場合はこちら

// 画像の倍率を元サイズのままとして幅と高さの情報を取得
const dims = image.scale(1);

// 画像ファイルと同じサイズのPDFページを追加して、画像を設定する
const page = pdfDoc.addPage([dims.width, dims.height]);
page.drawImage(image, {
  width: dims.width,
  height: dims.height,
});
const pdfBytes = await pdfDoc.save();


3.PDFファイルをS3に保存

最後に変換したPDFファイルをS3に保存にします。

// PDFファイルのbufferデータを取得
const pdfBuffer = Buffer.from(pdfBytes);

// S3に保存するためのパラメータを設定
const putParams = {
  Bucket: [S3バケット名],
  Key: [S3ファイルパス/PDFファイル名],
  Body: pdfBuffer,
  ContentType: 'application/pdf',
};

// S3に保存
await s3Client.putObject(putParams).promise();


以上で、変換したPDFファイルがS3に保存されました。
もし、画像からPDFへの変換が必要になった際に、参考になれば幸いです。


Catalinaにアップデートした後、pod installできないときの対処法。

12月 30, 2020

オフィス狛 技術部のmmm(むー)です。

既にBig Surがリリースされているので、少し今更感はありますがMac OSをCatalinaにアップデートした後、pod installが実行できなくなったのでその対処方法を記載します。
※ちなみにCatalinaのデフォルトシェルはzshですが、急いでいたのでひとまずbashで各作業は行っています。

実行環境
Xcodeのバージョンは諸事情で11系です...
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.15.7
BuildVersion:	19H15

$ xcodebuild -version
Xcode 11.1
Build version 11A1027

1. エラーの内容確認

1-1. pod installのエラーメッセージの確認
エラー内容から、CocoaPodsはrubyの2.3を使用しようとしているようですが、フォルダがないようです。
$ pod install

-bash: /usr/local/bin/pod: /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby: bad interpreter: No such file or directory

1-2. rubyのバージョン確認
Catalinaではデフォルトでrubyの2.6が入っているようです。
$ ruby --version

ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin19]

2. 対処方法

調査した結果、CocoaPodsを入れ直すと書かれていたので入れ直してみます。
gemを使用する方法と、brewを使用する方法があるようですが、今回はgemを使用します。

2-1. Xcodeのコマンドラインツール
その前にXcodeのコマンドラインツールが必要になるのでインストールします。
すでに入っている方は、下記のように表示されます。
$ xcode-select --install

xcode-select: error: command line tools are already installed, use "Software Update" to install updates

うまくインストールできない方は、公式から直接ダウンロードできるようです。
参考:https://developer.apple.com/download/more/

2-2. Xcodeとの紐付け
Xcodeにて、使用するコマンドラインツールの紐付けを行います。
既にこの作業が完了している方は、読み飛ばしてください。
(私はここが完了していなかったのですが、調べた数々のサイトにはこの手順の記載がなかったので時間が溶けました...)
Xcode > Preferences > Locations > Command Line Tools > XCode X.X.X(X.X.Xはバージョン)

2-3. CocoaPodsのインストール
$ sudo gem install cocoapods -n /usr/local/bin

pod insatll を行えたら、確認完了です。
以上となります、参考になりましたら幸いです。

参考にしたページ
This terminal won't let me run or install cocoa pods because I am on MacOS Catalina Beta? (stack overflow)
Brew based CocoaPods CLI fails in MacOS 10.15 Catalina due incorrect fallback to Ruby 2.3 #8955 (GitHubのCocoaPodsレポジトリのissue)

Angularでgetパラメータに配列を設定する方法。

12月 30, 2020
オフィス狛 技術部のHammarです。

前回6月くらいにAngularについて投稿したのですが、そこからお久しぶりのAngularについての投稿になります。
またご存知の方には基本的なお話しかもしれませんが、「angularでgetパラメータに配列をつかってリクエストする方法」についてご紹介しようと思います。
実はすこし前にKoma(Twitterアカウントの中の人&CEO)より「HttpParams を動的に追加したい。」という投稿で、配列形式でクエリパラメータを追加するという投稿があったのですが、これに少し似ている内容で、今回は1つのパラメータに配列を設定する方法になります。

まずは最初こんな感じでいけるのかなーと思って下記作ってみました。
※HogeInfoRequestModelにitemArrayという配列項目があるとします。
  getHogeInfo(req: HogeInfoRequestModel): Observable<HogeInfoModel> {
    const options = {
      params: new HttpParams()
        .set('items[]', req.itemArray)
    };
 
    return this.http.get('xxxxx/yyyyy/hoge/info', options).pipe(tap(console.log));
  }

上記で上手くいきそうな感じはするんですが、もちろん上手くいきません。。。

ここで「HttpParams を動的に追加したい。」の方法で、改めて配列追加という流れでやってももちろん大丈夫ですが、すでに配列になっている項目をリクエストしたい場合、下記のような記述方法でもいけました。

 getHogeInfo(req: HogeInfoRequestModel): Observable<HogeInfoModel> {
    const options = {
      params: new HttpParams()
        .set('items', JSON.stringify(req.itemArray))
    };
 
    return this.http.get('xxxxx/yyyyy/hoge/info', options).pipe(tap(console.log));
  }

JSON.stringifyを使ってここでJSON文字列に変換しちゃおうという方法です。

【注意!】結果的に、「配列を送っている」というのは正しくなく、ただの文字列を送っているにすぎないので、当然受け手側(WebAPI側)が、その文字列を配列に変換する必要があります。

配列項目をリクエストするという時には、用途に合わせて良き書き方で書いていただければと思います。

2020年11月27日金曜日

NgRx 8にて発生した「@ngrx/store: runtime checks are currently opt-in but ...」の警告の解決方法。

11月 27, 2020

オフィス狛 技術部のmmm(むー)です。

Angular8 + ngrx8を使用している担当プロジェクトで、ngrx/storeの警告がでているのが気になったので対処しました。

1. エラーメッセージの確認

@ngrx/store: runtime checks are currently opt-in but will be the default in the next major version with the possibility to opt-out, see https://ngrx.io/guide/migration/v8 for more information.
直訳:runtime checksは現在オプトイン形式がデフォルトですが、次のメジャーバージョンでオプトアウト形式になる可能性があります。詳細はサイトで確認してください。

これだけではさっぱりわからなかったので、メッセージに従いサイトを確認します。

2. ngrx バージョン8のアップデートガイド確認

色々書かれていますが、今回関連があるのは下記のようです。
A migration is provided to remove the usage ngrx-store-freeze, remove it from the package.json, and to enable the built-in runtime checks strictStateImmutability and strictActionImmutability.
直訳:ngrx-store-freezeの使用を取り除くマイグレーションが提供されます。package.jsonから削除して、ビルトインのruntime checks(strictStateImmutability とstrictActionImmutability)を有効にしてください。

要するに、ngrx7まではngrx-store-freezeを使用してStoreをimmutable(不変)にする必要があります。
しかし、ngrx8以上ではライブラリ不要になるので、runtime checksの値を設定してくださいとのことです。
弊社ではngrx-store-freezeを使用していませんが、同様にエラーが出ていました... とにかく設定しないといけないみたいです。

3. RuntimeChecksのページ確認

ページ内の記述方法を参考にstrictStateImmutabilitystrictActionImmutabilityの値を設定します。
ngrx-store-freezeを使用している場合は、設定している2つの項目はtrueにしてください。
// app.module.ts

StoreModule.forRoot(reducers),

  // ↓

StoreModule.forRoot(reducers, {
  runtimeChecks: {
    strictStateImmutability: false,
    strictActionImmutability: false
  }
}),

以上となります。
サイトに書いてあることをそのまま実行しただけですが、ngrxについて日本語で書かれているページがあまりないので、よければ参考にしてみてください。🍭

2020年11月25日水曜日

WindowsでDockerを利用してMySQLサーバーを立てる場合の注意点。

11月 25, 2020
オフィス狛 技術部のHammarです。

最近はnode.jsを触る機会がまた多くなってきたのですが、あるプロジェクトでAPIはnode.js、DBはMysqlを使うことになったので、Dockerでそれらのローカル環境を作り開発することにしました。
そこでWindowsとDockerの絡みでハマりポイントがあったので、ご紹介したいと思います。

※今回はDockerがWindows10環境にインストールされている前提で以下進めていきます。

まずDockerの起動にはdocker-compose.ymlを利用していきます。
そのdocker-compose.ymlには今回開発につかうAPIとDBの設定を下記のように記載します。
※今回DBの記述がメインとなるので、API側の記述は割愛します。
version: '3'
services:
  api:
	build:・・・
	・・・
  db:
    image: mysql:8.0
    command: mysqld --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_USER: user
      MYSQL_PASSWORD: pass
      TZ: 'Asia/Tokyo'
    ports:
      - "3306:3306"
    volumes:
      - './docker/dev/mysql/data:/var/lib/mysql'
      - './docker/dev/mysql/my.cnf:/etc/mysql/conf.d/my.cnf'
      - './docker/dev/mysql/sql:/docker-entrypoint-initdb.d'

上記のように書いて、あとは通常通り上記ymlを使ってDocker起動するだけです。
しかしながら、上記方法でMacでは上手くいくのですが、Windowsではなぜかうまくいきません。

これはWindowsはMacとは違い、WindowsはdockerをVirtualBox経由で起動させているためのようです。
こちら参考にさせていただきました。
https://qiita.com/waterada/items/1dbf6a977611e0e8f5c8

※ちなみにWindowsは上記が原因で、作りたい環境内容によっては他の問題も発生するようで、実際自分も別環境作成時にまた問題があったのですが、またそのあたり別の投稿で記載しようと思います。

ということでいろいろと調べた結果、mysqlの設定ファイルであるmy.cnfファイルを別途作成し、それをdocker起動時にマウントさせることによって本事象を解消できるということのようでした。

1.docker-compose.ymlを修正する

まずはdocker-compose.ymlを下記のように書き換えます。
version: '3'
services:
  api:
	build:・・・
	・・・
  db:
    image: mysql:8.0
    command: mysqld --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_USER: user
      MYSQL_PASSWORD: pass
      TZ: 'Asia/Tokyo'
    ports:
      - "3306:3306"
    volumes:
      - './docker/dev/mysql/sql:/docker-entrypoint-initdb.d'

2.my.cnfファイルを作成する

もともとDBの文字コードの設定もymlファイルのcommand部分に記載していたのですが、このあたりをmy.cnfに別途下記のように作成します。
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci

[client]
default-character-set=utf8mb4

3.Dockerfileを作成する

最後に上記のmy.cnfファイルをマウントさせるために、下記のようにDockerfileを作成し、そこでADDします。
またファイルの権限もデフォルトだと777となってしまい、mysqlは権限777のcnfファイルは読み込まないということなので、ADDしたあとに権限も変更するように記述します。
FROM mysql:8.0

ADD ./docker/dev/mysql/my.cnf /etc/mysql/conf.d/my.cnf

RUN chmod 644 /etc/mysql/conf.d/my.cnf

上記3つが整った状態で、ymlを使ってDocker起動すると、なんとかうまく起動されました。
上記手順書いてみると、なるほどなーと感じるのですが、これを全く知らないところから調べていったので、かなりハマって環境構築だけで結構時間がかかってしまいました。。。
そもそもやっぱりVirtualBox経由でDockerを利用することがいろいろな弊害を生んでいるようなので、このあたりWindowsユーザーは不利だなーと感じたのでした。

Illustrator2021のオブジェクトを再配色を試してみる。

11月 25, 2020


こんにちは、オフィス狛 デザイン部のSatoです。

先日アップデートされましたIllustrator2021で、以前ブログでご紹介した「オブジェクトを再配色」という機能がさらに便利になったようなのでご紹介します。

↓以前アップしたオブジェクトを再配色の記事です。

実は元々の機能の場所などが少し変わっていますので、「オブジェクトを再配色」画面の表示方法から説明していきます。 


色を変えたいオブジェクト全体を選択し、Illustratorメニューバーの「編集」の「カラーの編集」から「オブジェクトを再配色」を選ぶかツールバーの「オブジェクトを再配色アイコン」をクリックします。

以前は「オブジェクトを再配色パレット」が表示……されていたのですが、今回のアップデートから新しい「オブジェクトを再配色」画面が表示されるようになりました。

今まで最初に表示されていた「オブジェクトを再配色パレット」は右下に表示される「詳細オプション」ボタンをクリックすることで表示されるようになっています。
今まで通り再配色パレットを最初に表示したい場合ははオブジェクトを再配色パレットの左下に表示される「起動時に詳細オブジェクトを再配置ダイアログを開く」にチェックを入れましょう。
(新しい「オブジェクトを再配色」のダイアログが表示しづらくなるのであまりおすすめはできません)

新しくなったオブジェクトを再配色には「カラーテーマピッカー」や「目立つカラー」パレットなどの機能が追加されたのでご紹介したいと思います。 


最初にご紹介したいのはカラーテーマピッカーツールです。
なんとこの機能、選択したオブジェクトではない別の画像やオブジェクトの全体的な配色をつかって再配色してくれる機能です。
「カラーテーマピッカー」ボタンを押すとマウスカーソルがスポイトマークに変化するので参考にしたい画像をクリックしたり、Shift キーを押しながらクリックして複数選択したり、ドラッグして選択範囲を選択します。

画像を使い、Illustratorで描いたイラストの色を変えました

選択した画像でよく使われている色に変わりましたが、なんだか配色にメリハリがない配色になってしまいました。
こういう時にもう一つの新機能 「目立つカラー」パレットが役立ちます「目立つカラー」パレットの目立たせたい明度の高い色の端を横にドラッグして広げます。

「目立つカラー」パレットを調整してイラストがメリハリのある配色になりました!


オブジェクトを再配色を駆使し色をさらに調整してイラストを完成させました。

「カラーテーマピッカー」も「目立つカラー」も、よく色の参考に使っている「カラーライブラリ機能」よりもなかなか普段使わないような配色のデザインが作れるので、普段似たような色ばかり使ってしまうなあ……と悩んだ時に使ってみたい機能だと思います。


みなさんも配色に悩んだ際に「オブジェクトを再配色」の新しい機能を使ってみてください。