2020/03/11

Docker もう一度を最初から学ぶ為に、シリーズで書いていきます。

今回は、

  • Docker for Mac インストール&起動
  • docker コマンドを確認

Docker For Mac をインストール

Mac で Docker を始めるには「Docker For Mac」を利用するのがお手軽です。

公式のページの Docker For Mac から dmgファイル(※2020-03-02時点:version 2.2.2.0)をダウンロードします。

Docker for Mac

Docker for Mac のメニュー

Docker for Mac の基本設定

Docker の自動起動

Start Docker when you log in

自動アップデート

Automatically check for updates

CPU・メモリ設定

個人差がありますが、デフォルトで使用してみて足りないようなら変更してみると良いでしょう。

ホストOS側のマウント

「File Sharing」で、Dockerコンテナ側がマウントするディレクトリを設定できます。
差し当たり、デフォルトのままで良いと思います。

ネットワーク

Dockerコンテナが利用する、IPアドレスの範囲をしていします。
自分でカスタマイズしても構いませんが、差し当たりデフォルトにしておきます。

docker コマンドを使ってみる

Docker for Mac がインストールできたら、Mac のターミナルで docker コマンドを実行してみます。

Docker バージョン確認


$ docker --version
Docker version 19.03.5, build 633a0ea

Docker Getting Started コンテナ起動

今度はあらかじめ作成されている Dockerコンテナを起動してみます。

docker/getting-started というコンテナが Docker Hub に用意されているので、これを起動してみます。


$ docker run -dp 80:80 docker/getting-started

色々とオプションが入ってますが、わかりやすく書くと以下の通りとなります。


$ docker run オプション コンテナ名

run:コンテナを起動

今回の場合、docker/getting-started​ がコンテナイメージとなります。

-d:バックグラウンド起動

通常はこのバックグラウンドで起動します。

-p:ポート番号マッピング

ホスト側のポート番号と、コンテナ側のポート番号をマッピングします。


ホストポート番号:コンテナポート番号

コンテナ起動のオプションは、


$ docker run --help

で調べることができます。

起動中のコンテナ確認

コンテナを起動したら、コンテナの起動状況(プロセス)を確認します。


$ docker ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                NAMES
4abe131793c6        docker/getting-started   "nginx -g 'daemon of…"   31 minutes ago      Up 31 minutes       0.0.0.0:80->80/tcp   unruffled_roentgen

上記は、コンテナIDが「4abe131793c6」、コンテナイメージが「docker/getting-started」で起動しています。

Docker Getting Started をブラウザで確認

Mac側のポート80 と Docker側のポート80 がマッピングされているため、

http://localhost/

にアクセスすると、Webサーバを介してチュートリアルが表示されます。

Docker Getting StartedイメージのWebサーバは「nginx」が起動しているようです。

Docker Getting Started コンテナを停止

コンテナを停止します。


$ docker stop 4abe131793c6

引数は docker ps で記載されたコンテナIDを指定して


$ docker stop コンテナID

Docker For Mac は遅い?

Docker を利用する場合、Mac(ホスト) と Dockerコンテナ 間でディスク共有します。
ディスクマウントの仕様上、Docker For Mac は他のDocker環境に比べて速度が遅い(レイテンシー)傾向があります。
これは個人差があるので一概に言えませんが、開発できないレベルではありません。

  2020/03/03

何年振りかに MySQL を設定するためメモ

Homebrew でインストール


$ brew update
$ brew install mysql

MySQLバージョン確認


$ mysql --version

$ mysql  Ver 8.0.19 for osx10.14 on x86_64 (Homebrew)

MySQL 起動


$ mysql.server start

MySQL ログイン(root)


$ mysql -u root

MySQL 操作

MySQL バージョン


$ show variables like 'version'; 
+---------------+--------+
| Variable_name | Value  |

ユーザ確認


mysql> select user();
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+

ユーザ権限確認


mysql> show grants;

ユーザ作成 & パスワード設定


mysql > create user `ユーザ名`@`localhost` IDENTIFIED BY 'パスワード'

パスワード変更

MySQL5.7以上は PASSWORD 関数が使えません。


mysql > ALTER USER 'ユーザ名'@'localhost' identified BY 'パスワード'

ログイン(パスワード付き)


mysql> -u ユーザ名 -p

 

データベース一覧


mysql> show databases;

MySQL Workbench

Mac の MySQL クライアントツールは、Oracle の「MySQL Workbench」を利用しました。
(Sequel Pro などのサードパティーはリリースが不安定なので)

Oracle: MySQL Workbench

  2020/03/02

composer update したところ、ext-dom がないから PHPUnitが入れられないようです。


$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - phpunit/phpunit 8.5.x-dev requires ext-dom * -> the requested PHP extension dom is missing from your system.
...

php-xml をインストール


# aptitude update
# aptitude install php-xml

再度 composer update する

今度は、インストールが進み、vendor もインストールされた。


$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 87 installs, 0 updates, 0 removals
As there is no 'unzip' command installed zip files are being unpacked using the PHP zip extension.
This may cause invalid reports of corrupted archives. Besides, any UNIX permissions (e.g. executable) defined in the archives will be lost.
Installing 'unzip' may remediate them.
  - Installing symfony/polyfill-ctype (v1.14.0): Loading from cache
...

  2020/03/01

Eloquent で DBから日付を扱う場合、$date にカラム指定することで自動キャストされます。
(ただし、DBデータの日付フォーマットには注意が必要です)

日付カラム指定


    protected $dates = [
        'created_at',
        'updated_at',
        'posted_at',
    ];

Carbon フォーマット

$datesで指定したカラムは、DB取得データで Carbon にキャストされているため、以下のように Blade でも読みやすい記述ができます。

 
@foreach ($values as $value)
{{ $value->posted_at->format('Y/m/d') }}
@endforeach

フォーマット指定

日付フォーマットも指定できる。


protected $dateFormat = 'Y-m-d H:i:s.u'; 

が、DBデータフォーマットと不整合があると、Exception(Carbon の Create.php)が発生するので注意が必要です。

個人的には「Y-m-d H:i:s」にした方が無難な気がします。

PostgreSQLの場合

  • created_at は CURRENT_TIMESTAMP
  • timstamp without time zone
  • timestamp(0) 

明示的に指定する場合は、


$table->timestamp('created_at')->default(DB::raw('now()::timestamp(0)'));

  2020/02/27

webpackとは

webpack(ウェブパック)は、複数のJSファイルをまとめてくれるツールです。
webpackは「gulp」「Grunt 」「Browserify」のようなタスクランナーですが、最大の特徴は「モジュールバンドラ」です。

モジュールバンドラーはファイルをまとめることを指し、複数のモジュール(ここではJS)の依存関係を解決します。

今回は下記を参考にて webpack4 を npm で構築してみました。

参考

最新版で学ぶwebpack 4入門 JavaScriptのモジュールバンドラ

webpack の特徴

webpackのメリットはいくつかあります。

  • 複数のJSファイルを1つのファイル(main.js や bundle.js)にまとめる
  • HTTPリクエストの数を減らす
  • 設定ファイルに基づいて開発環境を統一できる
  • 「React」「Vue.js」をはじめとしたサードパティの JavaScript と連携して開発できる
  • CSSやリソース(画像など)もバンドルできる

 

など、今まで別々で管理していたJSファイルを1つにまとめることで、フロントエンド開発手法そのものが変わってきます。

gulp で開発してきた場合は、gulp + webpack で運用してるようですが、新規ならば webpack で十分みたいです(開発者の好みか?)。

Node.js の確認

node.js のバージョンは13以上


$ node -v
v13.6.0

プロジェクト作成

webpack のテストサンプルを利用するロジェクトを作成する。
また、npm init で package.json も作成しておく。


$ mkdir webpack-test
$ cd webpack-test
$ npm init -y
$ mkdir src

webpack のインストール

devDependencies(-D) で webpack webpack-cli をインストールする


$npm i -D webpack webpack-cli
...
+ webpack-cli@3.3.11
+ webpack@4.41.6
...

JavaScript をモジュールで実装

現時点で、「モジュール方式」で JavaScript を実装することが推奨されている。
※ECMAScript Modules(ES Modules、ESM)

webpack4 では明示的に指定しない場合、以下の設定となります。

  • 「src/index.js」がエントリーポイント
  • 「dist/main.js」が出力ファイル

JavaScript ファイル記述

src/index.js


import { say } from "./module1";
say();

src/person.js


export function say() {
    alert("module1 hello!");
}

webpackビルド

手っ取り早く npm 5.2.0 で追加された「npx」コマンドで webpack ビルドしてみる。
(npm run build で webpack を動作させた方が応用が効くが) 


$ npx webpack
Hash: 58e8f21bff04a84f6d5c
Version: webpack 4.41.6
Time: 247ms
Built at: 2020/02/27 20:49:44
  Asset       Size  Chunks             Chunk Names
main.js  957 bytes       0  [emitted]  main
Entrypoint main = main.js
[0] ./src/index.js + 1 modules 96 bytes {0} [built]
    | ./src/index.js 42 bytes [built]
    | ./src/person.js 54 bytes [built]

src/index.js に src/person.js が統合され dist/main.js が書き出される

HTML実装&確認

index.html を作成し「dist/main.js」を読み込む

npm でビルド

npx webpack でなく package.json を設定して npm ビルドする

package.json の設定

  • scripts の build に「webpack」
  • devDependencies に 「webpack」「webpack-cli」のパッケージを記述

{
  "name": "webpack-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "webpack": "^4.41.6",
    "webpack-cli": "^3.3.11"
  },
  "devDependencies": {
    "webpack": "^4.41.6",
    "webpack-cli": "^3.3.11"
  },
  "scripts": {
    "build": "webpack"
  }
}

npm ビルド

npm run build で webpack ビルドされる


$ npm run build
> webpack-test@1.0.0 build /Users/yoo/docker/projects/webpack-test
> webpack
...

webpack.config.js を設定してビルド

webpack.config.js を作成して、「entry」「output」を設定することで、エントリポイント、出力先ファイルをカスタマイズできます。

※前述の通り webpack4 では「src/index.js」「dist/main.js」がデフォルト


module.exports = {
  entry: `./src/index.js`,
  output: {
    path: `${__dirname}/dist`,
    filename: "main.js"
  },
  mode: "development"
};

$ npm run build 

modeを「development」にすると、出力ファイル(main.js)が圧縮されずに書き出されます。

ウォッチを利用するビルド

webpack-dev-server をして、JavaScriptの実装をリアルタイムにブラウザ確認することもできるが、一般的なウォッチを利用してビルドする。

package.json に watch を設定


  "scripts": {
    "build": "webpack",
    "watch": "webpack --watch"
  },

watch を起動


$ npm run watch

これで、JavaScript を保存すると自動でビルドされます。

  2020/02/14

MacBook Pro 256 で開発やクリエイティブ作業していくと容量が厳しくなってきた。

自分の場合

  • Xcode(iOSシミュレータ含む)
  • Homebrew
  • VirtualBox & Vagrant
  • Docker
  • Adobe Creative Cloud
  • DAW、音楽ライブラリ
  • 写真ライブラリ

がかなり容量を圧迫しています。

ファイルを検索

5G以上のファイル検索


$ sudo du -gxd 5 / | awk '$1 >= 5{print}'

1G以上のファイル検索(現在のディレクトリ)

$ sudo du -gxd 1| awk '$1 >= 1{print}'

これらをもとに、手動で削除

Xcode 端末シミュレータの削除

Xcodeの場合、ツールコマンドを利用する

端末リスト確認


$ xcrun simctl list devices
== Devices == 
-- iOS 13.3 
-- iPhone 8 (69D4A89A-704C-43E0-8C71-6437C551DEB6) (Shutdown) iPhone 11 (DC5B21DE-21CA-4624-8C1C-7CDC349B9DDA) (Shutdown) ... 
-- Unavailable: com.apple.CoreSimulator.SimRuntime.iOS-10-1 
-- iPhone 5 (CE4E79DC-CE71-47A9-B2C8-5F77EE73196F) (Shutdown) (unavailable, runtime profile not found) iPhone 5s (C94451DC-A342-46AE-8E69-52D6DF928E77) (Shutdown) (unavailable, runtime profile not found) 

不要端末削除


$ xcrun simctl delete unavailable

Docker

Dockerは不要なコンテナー、イメージが溜まりがち

イメージ一覧情報を表示


$ docker image ls

不要(none)の情報を表示


$ docker images -f dangling=true

不要(none)の情報を削除


$ docker image rm $(docker image ls  --filter "dangling=true" -aq)

イメージ・コンテナー・ボリュームの情報を表示


$ docker system df TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 85 0 18.97GB 18.97GB (100%) Containers 0 0 0B 0B Local Volumes 24 0 80.44MB 80.44MB (100%) Build Cache 0 0 0B 0B

停止中(exited)のイメージ・コンテナー・ボリュームを削除


$ docker system prune

全てのイメージ・コンテナー・ボリュームを削除


$ docker system prune -a

GrageBand 削除

別途DAWを入れているので、Garageband は削除


$ sudo rm -rf /Applications/GarageBand.app
$ sudo rm -rf /Library/Application\ Support/GarageBand
$ sudo rm -rf /Library/Application\ Support/Logic
$ sudo rm -rf /Library/Audio/Apple\ Loops
$ sudo rm -rf /Library/Audio/Apple\ Loops\ Index

  2020/02/08

DIについては、DI(依存性注入) を参照

DIコンテナは、DIのインスタンス生成を、別のファイルでコンテナ化して解決しようという設計パターンです。

共通クラスを用意

まず、共通で使う Animalクラスを用意します。
手っ取り早くファイル分割せず Animal.php にクラス(Dog、Cat)を記述しました。


interface Animal {
    public function bow();
}

class Dog implements Animal {
    public function bow() {
        echo 'wan! wan!'.PHP_EOL;
    }
}

class Cat implements Animal {
    public function bow() {
        echo 'nya-! nya-!'.PHP_EOL;
    }
}

DIでない例

下記のサンプルはコンストラクタ内で Dog を生成して鳴きます。


class AnimalConsole {
    protected $dog;

    public function __construct() {
        $this->dog = new Dog();
    }

    public function bow() {
        $this->dog->bow();
    }
}

$animal_console = new AnimalConsole();
$animal_console->bow();

この場合、コンストラクタで new Dog() するため、Dogが実装できるまで AnimalConsole が実装できません。

DI(?)の場合

コンストラクタの引数に、Dog、Cat インスタンスを注入します(コンストラクタインジェクション)
他の記事をみているとこれで「DI」となってますが、まだ Dog に依存しているため Cat に修正したい場合に手間がかかります。


require_once 'Animal.php';

class AnimalConsole {
    protected $dog;

    public function __construct(Dog $dog) {
        $this->dog = $dog;
    }

    public function bow() {
        $this->dog->bow();
    }
}

$animal_console = new AnimalConsole(new Dog());
$animal_console->bow();

インターフェイス(モック)を引数にしてみる

今度は Dog、Cat 両方扱えるように Amimal を引数とします。


require_once 'Animal.php';

class AnimalConsole {
    protected $animal;

    public function __construct(Amimal $animal) {
        $this->animal = $animal;
    }

    public function bow() {
        $this->animal->bow();
    }
}

$animal_console1 = new AnimalConsole(new Dog());
$animal_console1->bow();

$animal_console2 = new AnimalConsole(new Cat());
$animal_console2->bow();

これで、Dog、Cat どちらでも注入できるようになりました。

pimpleでDIコンテナを作成する

インスタンスを直接渡すのではなく、コンテナ(箱)内でインスタンスを作成して処理するのが、DIコンテナです。

今回は、composerのContainerライブラリ「pimple」を利用しています。

Pimpleインストール


$ composer require pimple/pimple ~3.0

PimpleによるDIコンテナ

下記の場合、Dog、Cat のインスタンスをコンテナ化しています。

また、$container['animal'] では、インスタンスを簡単に切り替えることができます。


require_once 'Animal.php';
require_once __DIR__.'/../vendor/autoload.php';

use Pimple\Container;

class AnimalConsole {
    protected $animal;

    public function __construct(
        Animal $animal
        ) {
        $this->animal = $animal;
    }

    public function bow() {
        $this->animal->bow();
    }
}

$container = new Container();

$container['dog'] = function($c) {
    return new Dog();
};

$container['cat'] = function($c) {
    return new Cat();
};

$container['animal'] = function($c) {
    return $c['dog'];
};

$container['animalConsole'] = function ($c) {
    return new AnimalConsole($c['animal']);
};

$container['animalConsole']->bow();

Container の部分はファイル分離する必要はあります。

  2020/02/06

Freee SDK

ありそうでなかった会計向けSDK
freee が国内初なようで、2020/02時点の対応言語は「C#」「Java」「PHP」

freee API と統制をとるために「OpenApi generator」を利用して有志が開発しているとのこと

C#

https://github.com/freee/freee-accounting-sdk-csharp/

Java

https://github.com/freee/freee-accounting-sdk-java

PHP

https://github.com/freee/freee-accounting-sdk-php/

PHPの場合は、composer で用意されており、さらにサンプル用に Docker & Laravel が公開されている。

サンプルの動作例

freee API

freee API

Docker & Laravel でサンプルを動かす

コールバックURL

freee APIアプリの「コールバックURL」は以下を設定しておく
※デフォルト:urn:ietf:wg:oauth:2.0:oob
※Laravel dでも後に設定する


http://localhost:8000/auth-callback

サンプルダウンロード & 設定

サンプルは SDK の中に入っているので git clone


$ git clone https://github.com/freee/freee-accounting-sdk-php.git

.env を設定する


$ cd <code>freee-accounting-sdk-php.git

freeeアプリ の Client ID、Secret ID を記述


FREEE_ACCOUNTING_CLIENT_ID=Client ID
FREEE_ACCOUNTING_CLIENT_SECRET=Secret ID

Dockerの起動

freee-accounting-sdk-php にあるサンプルを利用する

$ cd freee-accounting-sdk-php/samples/BasicWebApp
$ cd samples
$ docker-compose build
$ docker-compose up -d
$ docker exec -it samples_webapp_1 /bin/bash

docker-compose.yaml


version: "3.7"
services:
  console:
    build:
      context: .
      dockerfile: Dockerfile
    image: freee-accounting-sdk-php-console
    volumes:
      - "./BasicConsole:/usr/src/app"
    command: /bin/sh -c "while sleep 1000; do :; done"
  webapp:
    build:
      context: .
      dockerfile: Dockerfile
    image: freee-accounting-sdk-php-webapp
    ports:
      - "80:80"
      - "8000:8000"
    volumes:
      - "./BasicWebApp:/usr/src/app"
    command: /bin/sh -c "while sleep 1000; do :; done"

Dockerfile


FROM php:7.3-cli
RUN apt-get update; \
    curl -sL https://deb.nodesource.com/setup_12.x | bash -; \
    apt-get install -y --no-install-recommends \
        git \
        libzip-dev \
        nodejs \
        unzip \
        zlib1g-dev \
    ; \
    rm -rf /var/lib/apt/lists/*

RUN docker-php-ext-install zip
WORKDIR /tmp
RUN curl https://raw.githubusercontent.com/composer/getcomposer.org/76a7060ccb93902cd7576b67264ad91c8a2700e2/web/installer -o - -s | php -- --quiet; \
    mv composer.phar /usr/local/bin/composer
WORKDIR /usr/src/app
RUN composer global require laravel/installer
ENV PATH /root/.composer/vendor/bin:$PATH
EXPOSE 8000

Composer インストール

webpackが用意されているので、すぐインストールできる


# composer install

composer、Laravel を直にインストールする場合


$ composer require freee/freee-accounting-sdk
$ composer require socialiteproviders/generators
$ composer require socialiteproviders/manager

artisan で socialiteproviders/generators を実行


$ php artisan make:socialite FreeeAccounting --spec=oauth2 --authorize_url=https://accounts.secure.freee.co.jp/public_api/authorize --access_token_url=https://accounts.secure.freee.co.jp/public_api/token --user_details_url=https://api.freee.co.jp/api/1/users/me
$ composer dumpautoload

Laravel/UI を作成


$ composer require laravel/ui --dev
$ php artisan ui vue --auth
$ npm install && npm run dev

Laravel artisanサーバ起動


# php artisan key:generate
# php artisan serve
# php artisan serve --host 0.0.0.0

プロジェクトルートは「samples/BasicWebApp/」

認証処理

routes/web.php


Auth::routes([
    'register' => false,
    'reset' => false,
]);

Route::get('login', 'Auth\LoginController@redirectToProvider')->name('login');
Route::get('auth-callback', 'Auth\LoginController@handleProviderCallback')->name('authCallback');

config/service.php

「client_id」「client_secret」「redirect」をそれぞれ設定 (リダイレクトURLは、freeeのアプリ管理と合わせる)


 'freeeaccounting' => [
        'client_id' => env('FREEE_ACCOUNTING_CLIENT_ID'),
        'client_secret' => env('FREEE_ACCOUNTING_CLIENT_SECRET'),
        'redirect' => 'http://localhost:8000/auth-callback',
    ],

config/auth.php

freee用ドライバー、プロバイダー設定

    'defaults' => [
        'guard' => 'freee',
        'passwords' => 'users',
    ],
....
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'token',
            'provider' => 'users',
            'hash' => false,
        ],
        'freee' => [
            'driver' => 'freee',
            'provider' => 'freee',
        ],
    ],
...
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],
        'freee' => [
            'driver' => 'freee',
        ],
    ],

app\Http\Auth\LoginController.php

ログイン処理は、Laravel Socialite ドライバーを利用し、GenericUser で認証する


use App\Http\Controllers\Controller;
use Illuminate\Auth\GenericUser;
use Illuminate\Support\Facades\Auth;
use Socialite;

...

    public function redirectToProvider()
    {
        return Socialite::driver('freeeaccounting')->redirect();
    }

    public function handleProviderCallback()
    {
        $user = Socialite::driver('freeeaccounting')->user();

        $genericUser = $user->getRaw();
        $genericUser['token'] = $user->token;
        $genericUser['remember_token'] = '';
        Auth::login(new GenericUser($genericUser));

        return redirect()->intended($this->redirectTo);
    }

    public function logout()
    {
        Auth::logout();
        return redirect()->intended('/');
    }

認証用サービスプロバイダー

app/Providers/AuthServiceProvider.php


namespace App\Providers;

use App\Extensions\SampleSessionGuard;
use App\Extensions\FreeeUserProvider;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Auth;

class AuthServiceProvider extends ServiceProvider
{
  protected $policies = [
    // 'App\Model' => 'App\Policies\ModelPolicy',
  ];
  public function boot()
  {
    $this->registerPolicies();

    Auth::extend('freee', function ($app, $name, array $config) {
      return new SampleSessionGuard(
        $name,
        Auth::createUserProvider($config['provider']),
        $app['session.store']
      );
    });

    Auth::provider('freee', function ($app, array $config) {
      return new FreeeUserProvider();
    });
  }
}

イベントサービスプロバイダー

app/Providers/EventServiceProvider.php


namespace App\Providers;

use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
use SocialiteProviders\Manager\SocialiteWasCalled;
use SocialiteProviders\FreeeAccounting\FreeeAccountingExtendSocialite;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
        SocialiteWasCalled::class => [
            FreeeAccountingExtendSocialite::class,
        ],
    ];

    public function boot()
    {
        parent::boot();
    }
}

SocialiteProviders設定

SocialiteProviders/src/FreeeAccounting/Provider.php

https://api.freee.co.jp/api/1/users/me からユーザを返す関数を作成


    protected function getUserByToken($token)
    {
        $response = $this->getHttpClient()->get('https://api.freee.co.jp/api/1/users/me', [
            'headers' => [
                'Authorization' => 'Bearer '.$token,
            ],
        ]);

        $body = json_decode($response->getBody(), true);
        return $body['user'];
    }

User のマッピング


    protected function mapUserToObject(array $user)
    {
        $user['name'] = $user['last_name'] . ' ' . $user['first_name'];
        return (new User())->setRaw($user)->map([
            'id'       => $user['id'],
            'name'     => $user['name'],
            'email'    => $user['email'],
            'display_name' => $user['display_name'],
            'first_name' => $user['first_name'],
            'last_name' => $user['last_name'],
            'first_name_kana' => $user['first_name_kana'],
            'last_name_kana' => $user['last_name_kana'],
        ]);
    }

事業所と取引(収入/支出)一覧の取得

app/Http/AccountController.php

ログイン認証したユーザトークンを、Configuration クラスに設定


$user = Auth::user();
$config = Configuration::getDefaultConfiguration()->setAccessToken($user->token);
ちなみに、getAccessToken() でアクセストークンを確認できる。

$config->getAccessToken()

CompaniesApi で事業所IDを取得


$companiesApiInstance = new CompaniesApi(null, $config);
$companiesResponse = $companiesApiInstance->getCompanies();
$targetCompanyId = $companiesResponse->getCompanies()[0]->getId();

DealsApi で取引(収入/支出)一覧の取得


$limit = 5;
$dealsApiInstance = new DealsApi(null, $config);
$dealsResponse = $dealsApiInstance->getDeals(
            $targetCompanyId,
            null, null, null, null, null, null, null, null, null, null, null, null,
            $limit);
$deals = $dealsResponse->getDeals();

getDeals() の引数がちょっとどうなんだろ?

  2020/02/06

freee API は 開発者向けにOSS として公式公開されています。

https://developer.freee.co.jp/

 

ここでは、リファレンスを利用して認可コード・アクセストークン・API確認をしてみる。

実際の開発は各言語やSDKを使ってコーディングが必要だが、PHPに関しては、freee SDKを Laravel で使ってみる でやってみた。

開発者アカウント登録と環境・アプリ作成

まず、freeeアカウントを作成(一般ユーザアカウント)する

開発用テスト環境作成

次に開発ユーザでログインし、開発用テスト環境の作成する。

テスト環境の事業所を選択

アプリ追加

 アプリ追加画面でアプリを追加すると、Client ID, Client secret が発行される

作成したアプリは、アプリ管理 で管理する

freee API のドキュメント

API を試してみる

認可コード発行

「Webアプリ認証用URL」でブラウザでアクセスし、許可すると「認可コード」が発行される
※アクセストークンではない

アクセストークン発行

https://accounts.secure.freee.co.jp/public_api/authorize?client_id={client_id}&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=token 

上記のURLに freee アプリで発行された Client ID を入れてブラウザでリクエストする

事業所取得

https://developer.freee.co.jp/docs/accounting/reference#/Companies/get_companies

鍵マークをクリック

value に アクセストークンを入力して [Authorize]し、成功したら[Close]

[Try it out] をクリックし [Execute] するとAPIが実行される

事業所一覧取得API(companies)の場合

curl


curl -X GET "https://api.freee.co.jp/api/1/companies" -H "accept: application/json" -H "Authorization: Bearer {Client ID}"

Request Body


https://api.freee.co.jp/api/1/companies

Request URI


{
  "companies": [
    {
      "id": xxxxxxx,
      "name": "",
      "name_kana": "",
      "display_name": "個人事業主名",
      "role": "admin"
    },
    {
      "id": xxxxxxx,
      "name": null,
      "name_kana": null,
      "display_name": "個人事業主スタータープラン: 開発用テスト環境",
      "role": "admin"
    }
  ]
}

  2020/02/01

Segue を利用せずに Storyboard の Storyboard ID を利用して present で画面遷移させる。 遷移先の UIViewController を明示的にクラス名を指定すると値を渡すことも可能

画面遷移

  • 遷移元:ViewController
  • 遷移先:PageViewController
  • Storyboard ID:page

let storyboard: UIStoryboard = self.storyboard!
let page = storyboard.instantiateViewController(identifier: "page") as! PageViewController
page.customValue = customValue
page.modalPresentationStyle = .fullScreen
page.modalTransitionStyle = .crossDissolve
self.present(page, animated: true, completion: nil)
  1. Storyboard から instantiateViewController() で PageViewController を生成
  2. 値を受け渡し
  3. 画面遷移先の画面スタイル、アニメーションを設定

.modalPresentationStyle、.modalTransitionStyle プロパティは、iOSバージョンによって異なる

.modalTransitionStyle


public enum UIModalTransitionStyle : Int {
    case coverVertical
    case flipHorizontal
    case crossDissolve
    @available(iOS 3.2, *)
    case partialCurl
}

.modalPresentationStyle


public enum UIModalPresentationStyle : Int {
    case fullScreen
    @available(iOS 3.2, *)
    case pageSheet
    @available(iOS 3.2, *)
    case formSheet
    @available(iOS 3.2, *)
    case currentContext
    @available(iOS 7.0, *)
    case custom
    @available(iOS 8.0, *)
    case overFullScreen
    @available(iOS 8.0, *)
    case overCurrentContext
    @available(iOS 8.0, *)
    case popover
    @available(iOS 7.0, *)
    case none
    @available(iOS 13.0, *)
    case automatic
}
Cloud9 を起動する -初心者編-
gcloud で GCEインスタンスを起動してみる
AWS CLI と jq でインスタンス一覧を整形して表示
React と Laravel7 のプロジェクトを作成する
Homebrewインストール-2020年版
3直線で囲まれた範囲塗りつぶし
PuLP で線形最適化問題を解く
カスタムのペジネーションを作る
node-sass を使って sass をコンパイルする
Log ファサードでSQLログを分離して書き出す
いちから始める Docker - 複数のコンテナを使う - (2020年)
いちから始める Docker - docker-compose を使う - (2020年)
AWS ECR を使ってみる
Laravel7 でマルチ認証
Mac に AWS Client を設定する
Laravel 7 リリース
v-html でHTML表示する
Laravel で Vue コンポーネントを使う
Laravel で Nuxt.js を使ってみる(Docker環境)
いちから始める Docker -コンテナをビルド- (2020年)
いちから始める Docker -起動してみる- (2020年)
Mac で MySQL(8系)
composer で vendor がインストールできない
Eloquent の日付を Carbon で扱う
webpack 4 入門(npm編)
[Mac]容量を減らす
DIコンテナはじめ
freee SDKを Laravel で使ってみる
freee API を使ってみる
Segueを利用しない画面遷移
Xcode11.3 で XVim2 を利用する
Codable で JSONを読み込み
Webpack入門(yarn編)
MacからLaradock PostgreSQLで接続エラー
Dockerで不要なコンテナ・イメージを削除
Mac で Laradock の構築
Composer インストール
yarn インストール&プロジェクト作成
Laravel 6.x 構築(Homestead編)
nvm インストール
npm install が Mac でエラー
HTMLタグでカーソルが同時処理(ミラーリング)されてしまう
DI(依存性注入)
[Ubuntu]Let's Encryptで無料の証明書を利用する
[Apache]Apache2.4のアクセス制限が変更
[Ubuntu]rootのログインとsudo権限追加
タミヤ マイコンロボット工作セットをMacに接続してみた
pgAdimn4 でブラウザで開けなくなる
Java8 を HomebrewとjEnvで構築
Android Studio環境構築 2019