mmag

ハマったことメモなど

OpenAPIの3.0.0が出てた

1週間くらい前にリリースされていた模様。semverになってる。

github.com

気になるとこ

レスポンス深い

https://github.com/OAI/OpenAPI-Specification/tree/master/examples/v3.0 などの例をちらっと見た程度だけど、以下のようにレスポンスの書き方がやや深くなって、contentとかレスポンス形式をキーに持つようになっていた。多くの場合はapplication/jsonだと思うので省略したいように思うけど、どうやら省略することはできないっぽい。ちなみにapplication/jsonキーの値にあたるものをMedia Type Objectと呼ぶ。

get:
  responses:
    200:
      description: pet response
      content:
        application/json:
          schema:
            type: array

Components Object

Components Objectなるものが増えていた。

https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#componentsObject

これまで再利用したいオブジェクトはルートレベルにだらっと書かれていたけど、これらをまとめるような役割。

Server Object

https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#serverObject

servers:
  - url: https://sandbox.example.com/v1
    description: Sandbox server
  - url: https://example.com/v1
    description: Production server

これまではトップレベルあたりにhostというキーでIPやホスト名を1個だけ書けるようになっていたけど、複数のホストが書けるようになっていた。このパスへのリクエストはこのサーバしか受け付けませんよ、みたいに書ける。

'/pets':
  get:
    ...
  servers:
    - url: https://example.com/v1  # $refが使えないように読めるのが気になる
      description: Production server

2.0からのコンバータとかは無いよね、ですよね。

追記

よくよく見たらCallback ObjectとLink Objectっていうよくわからないやつらも追加されていた。

https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#callback-object

https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#link-object

Link Objectはクライアントに対して、「レスポンスのこのパラメータ使えばこっちのAPIこんな風に叩けるんすよ」っていうことを示すものっぽい。

Callback Objectは全く使い方がわからない。わからない。

カッコの周りの空白について

function foo() {
  ...
}

ていうコードを書いたらlintに怒られた。space-before-function-parenだそうで、

function foo () {
  ..
}

なら許してくださるらしい。

ギュってなってて読みづらいとかいう理由から生まれたんじゃないかと思うのだけど、エディタのフォント変えたほうがいいんじゃないですかという気分…。

同じように、{}()の内側にスペース入れる文化も、否定はしないけど、ちょっとなぁ。

こういう俺にとって見やすい見づらいみたいな水掛けになるルール、控えめに言って滅んでほしい。もうGitHubとかがまとめてlintしてください。

AngularのHttpを使うサービスの単体テスト

4系の話。Httpを使ってAPIアクセスするようなサービス(ここではPostService)のテスト。もう一度同じものを書けと言われても無理だなと思ったので書いておく。

import { TestBed, inject, async } from '@angular/core/testing';
import { MockBackend, MockConnection } from '@angular/http/testing';
import {
  Http, Response, RequestMethod, ConnectionBackend,
  RequestOptions, BaseRequestOptions, ResponseOptions
} from '@angular/http';

import { PostService, Post } from './post.service';

describe('PostService', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        {provide: ConnectionBackend, useClass: MockBackend},
        {provide: RequestOptions, useClass: BaseRequestOptions},
        Http,
        PostService
      ]
    });
  });

  describe('fetchAll', () => {
    beforeEach(inject([ConnectionBackend], (mockBackend: MockBackend) => {
      mockBackend.connections.subscribe((connection: MockConnection) => {
        expect(connection.request.method).toEqual(RequestMethod.Get);

        connection.mockRespond(new Response(new ResponseOptions({
          status: 200,
          body: {
            posts: [{content: "Hello"}, {content: "Goodbye"}]
          }
        })));
      });
    }));

    it('should return list of posts', async(inject([PostService], (service: PostService) => {
      service.fetchAll().subscribe((posts: Post[]) => {
        expect(posts[0].body).toEqual("Hello");
        expect(posts[1].body).toEqual("Goodbye");
      });
    })));
  });
});

テストコード中で投げたリクエストが、ConnectionBackenduseClassに設定したMockBackendconnectionsに流れてくるので、それに対する応答をbeforeEachで設定している。リアクティブ。

あとはsubscribeの中でexpectすることになるので、itの第2引数をasyncで包むとこが忘れがちポイント。

Testing Angular 2 Services and Http with Jasmine などを参考にしました。

テーマはFB matteをベースにしてます。作者さんに感謝を込めて。