$30 off During Our Annual Pro Sale. View Details »

KotlinでAPIを型安全にした話

noripi
December 19, 2017

 KotlinでAPIを型安全にした話

2017.12.19 R.kt#2の発表で使用したスライドです。

noripi

December 19, 2017
Tweet

More Decks by noripi

Other Decks in Technology

Transcript

  1. ,PUMJOͰ"1*Λܕ҆શʹͨ͠࿩
    3LU
    /PSJZVLJ*TIJEB

    View Slide

  2. ͍͋ͭࣗ͝͞ݾ঺հ

    ɾ໊લ/PSJZVLJ*TIJEB

    ɾαʔόαΠυʢ,PUMJO+BWB1)11ZUIPO

    ɾΤϯδχΞ!3FUUZ
    ɾJ04 4XJGU0CKFDUJWF$

    ɾ"84΋ͦͦ͜͜৮Δ
    ɾ,PUMJOྺ೥ϲ݄͘Β͍
    ɾ,PUMJO͔Θ͍͍
    ɾ࠷ۙ,PUMJO͗ͯ͢͠+BWBΛ๨Ε͖ͯͨ
    ɾ,PUMJO/BUJWFʹ΋ظ଴͍ͯ͠Δ
    IUUQTRJJUBDPNOPSJQJJUFNTFFDCEBDBGCE

    View Slide

  3. ຊ೔ͷ͓࿩

    ɾ,PUMJOΛಋೖͨ͠ܦҢ
    ɾ,PUMJOʹͯ͠Έͯײͨ͜͡ͱ

    View Slide

  4. ࠃ಺/P໊࣮άϧϝαʔϏε3FUUZͷӡӦ
    ೥ઃཱ
    XFCͱΞϓϦͰαʔϏεల։
    γϯάϧυϝΠϯ
    εϚϗϑΝʔετ
    ݄ؒར༻ऀ਺ສ

    View Slide

  5. 3FUUZ

    ɾ8FC
    ɾΞϓϦ

    View Slide

  6. ฐࣾʹ͓͚Δ,PUMJO

    ɾΞϓϦ༻"1*ʹ,PUMJOΛ࢖͍ͬͯ·͢
    ϒϥ΢β
    ΞϓϦ
    8FCΞϓϦέʔγϣϯαʔό
    "1*αʔό
    %#

    View Slide

  7. ,PUMJOΛಋೖͨ͠ܦҢ

    View Slide

  8. 1)1Ͱ࡞ΒΕ͍ͯͨ"1*


    ɾ8FCΞϓϦέʔγϣϯʹ"1*Λੜ΍͍ͯͨ͠
    ϒϥ΢β
    ΞϓϦ
    8FCΞϓϦέʔγϣϯαʔό
    "1*αʔό
    %#
    ɾࣾ಺ʹ1)1Λॻ͚Δਓ͕ଟ͘։ൃεϐʔυ΋଎͍

    View Slide

  9. 1)1Ͱ࡞ΒΕ͍ͯͨ"1*


    ɾ౰࣌ͷ"1*ͷಛ௃
    ɾฦΓ஋͸΄΅+40/ܗ͕ࣜͩҧ͏͜ͱ΋͋Δ
    ɾ+40/ͷLFZʹೖΔ஋ͷܕ͕Ұҙʹఆ·Βͳ͍
    ɾͲͷLFZʹͲΜͳ஋͕ೖͬͯ͘Δ͔ɺιʔείʔυΛݟͳ͍ͱ෼͔Βͳ͍
    ɾ͍ͭͰ΋Ͳ͜Ͱ΋0,
    ΞϓϦ
    8FCΞϓϦέʔγϣϯαʔό
    ˓˓ͷҰཡ͍ͩ͘͞ʂʢ͖ͬͱ"SSBZʣ
    GBMTF
    ɾฦΓ஋ͷόϦσʔγϣϯʢͦΕ͕ࣦഊ͔Ͳ͏͔΋ؚΊʣ͸ΫϥΠΞϯτଆͷ੹຿

    View Slide

  10. 1)1͔Β+BWB΁

    ɾ8FCΞϓϦέʔγϣϯͱ෼཭ͯ͠+BWB΁
    ɾαʔόαΠυݴޠͱ࣮ͯ͠੷͕͋Γɺ'8΋๛෋
    ɾΞϊςʔγϣϯͰ"1*ΛγϯϓϧʹఆٛͰ͖Δ+"934ͱ͍͏࢓༷͕͋Δ
    ΞϓϦ
    "1*αʔό
    ˓˓ͷҰཡ͍ͩ͘͞ʂʢ͖ͬͱ"SSBZʣ
    <\^ \^>
    ɾฦΓ஋ͷܕΛ10+0 ී௨ͷ+BWBΦϒδΣΫτ
    Ͱࣄલʹఆٛ
    ˠܕ҆શͳ"1*ͰΞϓϦΤϯδχΞʹฏ࿨ͳੈքΛ
    ɾࣦഊͨ͠ΒYYYYΛฦ͢

    View Slide

  11. ɾ+BWBͩͬͨͷͰ݁ߏϞμϯͳॻ͖ํ͕Ͱ͖͍ͯͨ
    +BWB͔Β,PUMJO΁ͷҠߦ


    ɾ࣮͸Ҡߦ͢Δͭ΋Γ͸ͳ͔ͬͨ
    ɾ1)1ͷࠒͱൺ΂ͯ"1*͕֨ஈʹྑ͘ͳͬͯɺຬ଍͍ͯͨ͠

    View Slide

  12. +BWB͔Β,PUMJO΁ͷҠߦ


    ɾҠߦͨ͠ཧ༝
    ɾ͋Δ೔ಥવ͜Μͳ΋ͷ͕
    ˠ͓΋ΉΖʹ,PUMJO͕ಋೖ͞Εͨ

    View Slide

  13. "1*ͷݱࡏ

    ΏΔ΍͔ʹ,PUMJOԽΛਐߦத

    View Slide

  14. ,PUMJOʹͯ͠Έͯײͨ͜͡ͱ

    View Slide


  15. ɾ͢ΜͳΓಋೖͰ͖Δ
    ɾطʹ+BWBͷϓϩμΫτ͕͋Δ৔߹ɺͦ͜ʹ,PUMJOΛೖΕΔͷ͸ͱͯ΋؆୯
    ɾ+BWBͩͱಈ͍ͨͷʹॻ͖׵͑ͨΒಈ͔ͳ͘ͳͬͨɺͱ͍͏͜ͱ͸·ͣͳ͍
    ,PUMJOʹͯ͠Έͯ
    ɾ͋Δ6UJMJUZ͚ͩॻ͖׵͑ͱ͍͏͜ͱ΋؆୯
    ɾ,PUMJO͔Θ͍͍
    ɾ/6--ڐ༰ܕܕਪ࿦ϥϜμͳͲϞμϯͳݴޠͷػೳΛҰ௨Γඋ͑Δ
    ɾ+BWB͔ΒͪΌΜͱίʔϧͰ͖ΔͷͰ+BWB͔͠ॻ͔ͳ͍ਓ͕͍ͯ΋҆৺
    ɾൺֱతετϨεগͳ͘ॻ͚Δݴޠͷͭ
    ɾ࢖͑͹࢖͏΄ͲΑΓྑ͍ॻ͖ํ͕ݟ͔ͭͬͯ͘Δ

    View Slide

  16. Ҡߦͯ͠ؾ͍ͮͨ,PUMJOͷϝϦοτ


    ɾ/VMMBCJMJUZΛίϯύΠϥϨϕϧͰఆٛͰ͖Δ
    ɾͦ΋ͦ΋1)1͔ΒҠߦͨ͠໨త͸ɺฦΓ஋ͷܕΛݫີʹఆٛ͢Δ͜ͱ
    ɾ+BWB࣌୅ʹ͸!/VMMBCMFΞϊςʔγϣϯͰදݱ͍͕ͯͨ͠ɺίϯύΠϥ

    ɹνΣοΫ͕ͳ͍ͨΊ࣮ଶͱҟͳ͍ͬͯͨ
    ɾΫϥΠΞϯτଆ͕0QUJPOBMͷػߏΛ࣋ͭݴޠͰॻ͔ΕΔ͜ͱ͕૿͖͍͑ͯͯΔ
    ˠ/6--ڐ༰͔Ͳ͏͔Λهड़͢Δ͜ͱ͸ɺܕΛهड़͢Δ

    ɹ͜ͱͱಉ͘͡Β͍ॏཁ

    View Slide

  17. Ҡߦͯ͠ؾ͍ͮͨ,PUMJOͷϝϦοτ


    ɾσʔλϗϧμΫϥεͷఆٛ
    ɾฦΓ஋ͷܕΛ10+0 ී௨ͷ+BWBΦϒδΣΫτ
    Ͱࣄલʹఆٛ͢Δඞཁ͕͋Δ
    ɾ+BWBͩͱఆٛ͢Δͷ͕ͪΐͬͱΊΜͲ͍͘͞
    public class GetRestaurantResponse {
    private long restaurantId;
    private String restaurantName;
    public long getRestaurantId() {
    return this.restaurantId;
    }
    public String getRestaurantName() {
    return this.restaurantName;
    }
    }

    View Slide

  18. Ҡߦͯ͠ؾ͍ͮͨ,PUMJOͷϝϦοτ


    ɾσʔλϗϧμΫϥεͷఆٛ
    ɾ,PUMJOͷ৔߹ɺEBUBDMBTTΛ࢖͑͹γϯϓϧʹهड़Ͱ͖Δ
    data class GetRestaurantResponse(
    val restaurantId: Long,
    val restaurantName: String
    )

    View Slide

  19. Ҡߦͯ͠ؾ͍ͮͨ,PUMJOͷϝϦοτ


    ɾ$MBTT%FMFHBUJPO
    ɾجຊతͳܕΛ૊Έ߹ΘͤͯฦΓ஋Λ࡞Γ͍ͨέʔε͸ׂͱΑ͋͘Δ
    ɾ+BWBͩͱఆٛ͢Δͷ͕͍ͩͿΊΜͲ͍͘͞
    public class GetReviewResponse implements IReview, IRestaurant,
    IUser {
    private IReview review;
    private IRestaurant restaurant;
    private IUser user;
    public long getReviewId() { return this.review.getReviewId(); }
    public String getUserName() { return this.user.getUserName(); }
    public String getRestaurantName() {
    return this.restaurant.getRestaurantName();
    }
    ...
    }

    View Slide

  20. Ҡߦͯ͠ؾ͍ͮͨ,PUMJOͷϝϦοτ


    ɾ$MBTT%FMFHBUJPO
    ɾΠϯλϑΣʔεͷ࣮૷ΛଞͷΫϥεʹҠৡͰ͖Δ
    ɾQSPQFSUZΛࡉ͔͘JOUFSGBDFԽ͓͚ͯ͠͹ɺฦΓ஋ΫϥεΛࡉ͔͘ఆٛՄೳʹ
    data class GetReviewResponse(
    private val review: IReview,
    private val restaurant: IRestaurant,
    private val user: IUser
    ) : IReview by review,
    IRestaurant by restaurant,
    IUser by user
    {
    // ෳ਺ͷinterfaceͰఆ͕͔ٛͿͬͯΔͱ͖͚ͩ໌ࣔతʹࢦఆ
    override val userId: Int = this.user.userId
    }

    View Slide

  21. ·ͱΊ

    ɾ,PUMJO͸͢ΜͳΓಋೖͰ͖Δʂ
    ɾฐࣾͰ΋ɺ͋Δ೔͓΋ΉΖʹ,PUMJO͕௥Ճ͞Ε͔ͯͦ͜ΒঃʑʹҠߦ͍ͯ͠·͢
    ɾ,PUMJOͷ͍͍ͱ͜Ζ

    ɾطʹ+BWBͷϓϩμΫτ͕͋Δ৔߹ɺͦ͜ʹ,PUMJOΛೖΕΔͷ͸ͱͯ΋؆୯
    ɾ/VMMڐ༰ܕͰ֎෦ΠϯλϑΣʔεΛΑΓݫີʹఆٛͰ͖Δ
    ɾEBUBDMBTTΛ࢖ͬͯσʔλϗϧμΛγϯϓϧʹఆٛͰ͖Δ
    ɾ$MBTT%FMFHBUJPO
    ɾଞʹ΋͍Ζ͍Ζ

    View Slide