Upgrade to Pro — share decks privately, control downloads, hide ads and more …

実践!Swift API Design Guidelinesに基づいた簡潔明瞭なAPIの作り方

Yusaku Nishi
September 26, 2023

実践!Swift API Design Guidelinesに基づいた簡潔明瞭なAPIの作り方

後夜祭 iOSDC Japan 2023 登壇資料
https://andpad.connpass.com/event/290856/

コードを読みやすく・挙動を予測しやすくするために、SwiftのAPI Design Guidelinesを活用しましょう。

本トークでは実際のコード例をもとに

- ガイドラインの示すAPIの理想像とは?
- API設計における大事な観点とは?

を解説します。
APIの構成要素すべてを洗練させ、簡潔明瞭で美しいAPIをデザインしましょう!

Yusaku Nishi

September 26, 2023
Tweet

Other Decks in Programming

Transcript

  1. $PQZSJHIU˜1SFTFOU"/%1"%*OD5IJTJOGPSNBUJPOJTDPOGJEFOUJBMBOEXBTQSFQBSFECZ"/%1"%*ODGPSUIFVTFPGPVSDMJFOU*UJTOPUUPCFSFMJFEPOCZBOESEQBSUZ1SPQSJFUBSZ$POGJEFOUJBMແஅసࡌɾແஅෳ੡ͷېࢭ
    ࣮ફʂSwift API Design Guidelinesʹج͍ͮͨ
    ؆ܿ໌ྎͳAPIͷ࡞Γํ
    ੢ ༔࡞

    View Slide

  2. ੢ ༔࡞ @jrsaruo_tech
    ΞχϝɹອըɹήʔϜɹSwift
    1996೥12݄21೔ੜ
    גࣜձࣾΞϯυύου
    େࡕग़਎
    ੢ ஀ੜ
    ੢ ੒௕

    View Slide

  3. SwiftͷAPI Design Guidelinesͱ͸
    APIɿApplication Programming Interface
    Swiftʹ͓͚Δʰྑ͍APIʱͷ࡞ΓํΛࣔͨ͠΋ͷ
    ϝιου΍ϓϩύςΟͱ͍ͬͨΠϯλʔϑΣΠε

    https://www.swift.org/documentation/api-design-guidelines/

    View Slide

  4. API Design Guidelinesͷࣔ͢ʰྑ͍APIʱͱ͸ʁͦΕΛ࡞Δʹ͸ʁ
    ຊ೔࿩͢͜ͱ
    ͜Μͳ࿩΋͔ͨͬͨ͠Ͱ͕͢ຊ೔͸ׂѪɿ
    move(destination:)ΑΓ΋move(to:)ʂ
    bookId͡Όͳͯ͘bookIDʂ shopUrl͡Όͳͯ͘shopURLʂ

    View Slide


  5. let string = input.message.trim()


    let mail = try await Mailer.sendMail(string, to: "Taro")
    mailBox.update(mail: mail, bottom: false)
    ԿΛτϦϛϯά͍ͯ͠Δʁ
    input.messageࣗମΛՃ޻͍ͯ͠Δʁ
    ԿΛ͍ͯ͠Δʁ
    bottom: falseͱ͸ʁ
    trueʹ͢ΔͱͲ͏ͳΔʁ
    ϝʔϧΞυϨεͰ͸ͳ͘ਓ໊ʁ
    🤔

    View Slide

  6. let message = input.message.trimmingWhitespaces()
    let sentMail = try await Mailer.send(message, toAddress: "Taro")
    mailBox.insert(sentMail, at: .top)

    🙂
    Ҿ਺ؒҧ͑ͯΔʂ

    View Slide

  7. એݴଆҎ্ʹར༻ଆͰͷ໌շ͕͞࠷ॏཁ
    API Design Guidelines - Fundamentals
    ؆ܿ͞ΑΓ΋໌շ͞ͷํ͕େࣄ
    ϝιου΍ϓϩύςΟͷએݴ͸1Օॴ͕ͩར༻͸ෳ਺Օॴ
    ؆ܿ͞͸SwiftͷݴޠػೳʹΑΔ෭࣍ޮՌɻΰʔϧͰ͸ͳ͍

    υΩϡϝϯτίϝϯτ΋ॻ͜͏Ͷ

    View Slide

  8. ໌շͱ͸ʁ

    View Slide

  9. ڍಈΛ༧ଌ͠΍͍͢
    ໌շͳAPIͱ͸
    ࢖͍ؒҧ͑ʹ͍͘ɺؒҧͬͨ࢖͍ํ͕Ͱ͖ͳ͍
    ʮݺͿͱԿ͕ى͖Δͷ͔ʯ͕͸͖ͬΓ෼͔Δ
    ࢖͍ํ͕෼͔Γ΍͍͢

    View Slide

  10. ৘ใΛෆ଍ͤ͞ͳ͍
    ໌շͳAPIΛઃܭ͢Δʹ͸
    ৘ใΛ๞࿨ͤ͞ͳ͍
    ৘ใ͕ଟ͗͢Δͱೝ஌ෛՙ্͕͕Δ
    ৘ใ͕গͳ͗͢ΔͱᐆດʹͳΔ

    View Slide

  11. ৑௕͞͸ͳ͍͔ʁ
    APIͷ໾ׂ͸ʁ
    ໌շͳAPIΛઃܭ͢ΔͨΊͷ4ͭͷ໰͍
    ৘ใ͸଍Γ͍ͯΔ͔ʁ
    ෭࡞༻͸͋Δ͔ʁࣗ਎Λมߋ͢Δ͔ʁ

    View Slide


  12. let mail = try await Mailer.sendMail(string, to: "...")
    mailBox.update(mail: mail, bottom: false)
    let string = input.message.trim()

    View Slide

  13. let string = input.message.trim()
    func trim() -> String

    Q. APIͷ໾ׂ͸ʁ
    Q. ࣗ਎Λมߋ͢Δ͔ʁ
    ༨നΛτϦϛϯάͨ͠จࣈྻΛฦ͢
    Q. ৑௕͞͸ͳ͍͔ʁ
    Q. ৘ใ͸଍Γ͍ͯΔ͔ʁ

    View Slide

  14. let string = input.message.trimWhitespaces()
    func trimWhitespaces() -> String

    Q. APIͷ໾ׂ͸ʁ
    Q. ࣗ਎Λมߋ͢Δ͔ʁ
    ༨നΛτϦϛϯάͨ͠จࣈྻΛฦ͢
    ͠ͳ͍
    Q. ৑௕͞͸ͳ͍͔ʁ
    Q. ৘ใ͸଍Γ͍ͯΔ͔ʁ
    FEɺJOHܗʹ͢Δ

    View Slide


  15. let string = input.message.trimmingWhitespaces()
    func trimmingWhitespaces() -> String
    Q. APIͷ໾ׂ͸ʁ
    Q. ࣗ਎Λมߋ͢Δ͔ʁ ͠ͳ͍
    Q. ৑௕͞͸ͳ͍͔ʁ 0,
    Q. ৘ใ͸଍Γ͍ͯΔ͔ʁ 0,
    FEɺJOHܗʹ͢Δ
    ༨നΛτϦϛϯάͨ͠จࣈྻΛฦ͢

    View Slide


  16. let mail = try await Mailer.sendMail(string, to: "...")
    mailBox.update(mail: mail, bottom: false)
    let string = input.message.trimmingWhitespaces()

    View Slide


  17. let mail = try await Mailer.sendMail(string, to: "...")
    func sendMail(


    _ message: String,


    to destinationAddress: String


    ) async throws -> Mail
    Q. APIͷ໾ׂ͸ʁ
    Q. ෭࡞༻͸͋Δ͔ʁ
    ࢦఆͷѼઌʹϝʔϧΛૹ৴͢Δ
    ͋Δ
    Q. ৑௕͞͸ͳ͍͔ʁ
    Q. ৘ใ͸଍Γ͍ͯΔ͔ʁ to͚ͩͰ͸ͲΜͳจࣈྻͳͷ͔ར༻ଆͰ෼͔Γʹ͍͘
    ໋ྩܗʹ͢Δ ܕ৘ใ͕ऑ͍ͱى͖͕ͪ
    Any, Int, String, ...

    View Slide


  18. func sendMail(


    _ message: String,


    toAddress destinationAddress: String
    ) async throws -> Mail
    Q. APIͷ໾ׂ͸ʁ
    Q. ෭࡞༻͸͋Δ͔ʁ
    ࢦఆͷѼઌʹϝʔϧΛૹ৴͢Δ
    ͋Δ
    Q. ৑௕͞͸ͳ͍͔ʁ Mail͸ແͯ͘΋఻ΘΔʢMailer͔ΒਪଌͰ͖Δʣ
    Q. ৘ใ͸଍Γ͍ͯΔ͔ʁ
    let mail = try await Mailer.sendMail(string, toAddress: "...")
    ໋ྩܗʹ͢Δ ܕ৘ใ͕ऑ͍ͱى͖͕ͪ
    Any, Int, String, ...
    to͚ͩͰ͸ͲΜͳจࣈྻͳͷ͔ར༻ଆͰ෼͔Γʹ͍͘

    View Slide


  19. func send(


    _ message: String,


    toAddress destinationAddress: String
    ) async throws -> Mail
    Q. APIͷ໾ׂ͸ʁ
    Q. ෭࡞༻͸͋Δ͔ʁ
    ࢦఆͷѼઌʹϝʔϧΛૹ৴͢Δ
    ͋Δ
    Q. ৑௕͞͸ͳ͍͔ʁ Mail͸ແͯ͘΋఻ΘΔʢMailer͔ΒਪଌͰ͖Δʣ
    Q. ৘ใ͸଍Γ͍ͯΔ͔ʁ
    let mail = try await Mailer.send(string, toAddress: "...")
    ໋ྩܗʹ͢Δ ܕ৘ใ͕ऑ͍ͱى͖͕ͪ
    Any, Int, String, ...
    to͚ͩͰ͸ͲΜͳจࣈྻͳͷ͔ར༻ଆͰ෼͔Γʹ͍͘

    View Slide


  20. let string = input.message.trimmingWhitespaces()
    mailBox.update(mail: mail, bottom: false)
    let mail = try await Mailer.send(string, toAddress: "...")

    View Slide


  21. func update(mail: Mail, bottom: Bool)
    Q. APIͷ໾ׂ͸ʁ
    Q. ࣗ਎Λมߋ͢Δ͔ʁ
    ϝʔϧΛϝʔϧϘοΫεͷτοϓʹૠೖ͢Δ
    Q. ৑௕͞͸ͳ͍͔ʁ
    Q. ৘ใ͸଍Γ͍ͯΔ͔ʁ
    mailBox.update(mail: mail, bottom: false)

    View Slide


  22. func insert(mail: Mail, bottom: Bool)
    Q. APIͷ໾ׂ͸ʁ
    Q. ࣗ਎Λมߋ͢Δ͔ʁ
    ϝʔϧΛϝʔϧϘοΫεͷτοϓʹૠೖ͢Δ
    Q. ৑௕͞͸ͳ͍͔ʁ
    Q. ৘ใ͸଍Γ͍ͯΔ͔ʁ
    mailBox.insert(mail: mail, bottom: false)
    ໨తޠ

    View Slide


  23. func insertMail(_ mail: Mail, bottom: Bool)
    Q. APIͷ໾ׂ͸ʁ
    Q. ࣗ਎Λมߋ͢Δ͔ʁ
    ϝʔϧΛϝʔϧϘοΫεͷτοϓʹૠೖ͢Δ
    ͢Δ
    Q. ৑௕͞͸ͳ͍͔ʁ
    Q. ৘ใ͸଍Γ͍ͯΔ͔ʁ bottom: false͸ᐆດ
    mailBox.insertMail(mail, bottom: false)
    ໋ྩܗʹ͢Δ
    enumʹͯ͠ΈΔ

    View Slide


  24. func insertMail(_ mail: Mail, at position: InsertPosition)
    Q. APIͷ໾ׂ͸ʁ
    Q. ࣗ਎Λมߋ͢Δ͔ʁ
    ϝʔϧΛϝʔϧϘοΫεͷτοϓʹૠೖ͢Δ
    ͢Δ
    Q. ৑௕͞͸ͳ͍͔ʁ
    Q. ৘ใ͸଍Γ͍ͯΔ͔ʁ
    Mail͸ແͯ͘΋఻ΘΔ
    bottom: false͸ᐆດ
    mailBox.insertMail(mail, at: .top)
    ໋ྩܗʹ͢Δ
    enumʹͯ͠ΈΔ

    View Slide


  25. func insert(_ mail: Mail, at position: InsertPosition)
    Q. APIͷ໾ׂ͸ʁ
    Q. ࣗ਎Λมߋ͢Δ͔ʁ
    ϝʔϧΛϝʔϧϘοΫεͷτοϓʹૠೖ͢Δ
    ͢Δ
    Q. ৑௕͞͸ͳ͍͔ʁ
    Q. ৘ใ͸଍Γ͍ͯΔ͔ʁ
    Mail͸ແͯ͘΋఻ΘΔ
    bottom: false͸ᐆດ
    mailBox.insert(mail, at: .top)
    ໋ྩܗʹ͢Δ
    enumʹͯ͠ΈΔ

    View Slide


  26. string = input.message.trimmingWhitespaces()
    string, toAddress: "...")
    mail = try await Mailer.send(
    let


    let
    mailBox.insert(mail, at: .top)

    View Slide


  27. message = input.message.trimmingWhitespaces()
    message, toAddress: "...")
    mail = try await Mailer.send(
    let


    let
    mailBox.insert(mail, at: .top)
    mailBox.insert(mail, at: .top)

    View Slide


  28. sentMail = try await Mailer.send(message, toAddress: "...")
    message = input.message.trimmingWhitespaces()
    let


    let
    mailBox.insert(sentMail, at: .top)

    View Slide


  29. sentMail = try await Mailer.send(message, toAddress: "...")
    message = input.message.trimmingWhitespaces()
    let


    let
    let string = input.message.trimString()
    let mail = try await Mailer.sendMail(string, to: "...")
    mailBox.update(mail: mail, bottom: false) 🤔
    🙂
    mailBox.insert(sentMail, at: .top)

    View Slide

  30. API Design GuidelinesΛಡ΋͏
    ར༻ଆͰͷ໌շ͞Λॏࢹ͠Α͏
    ·ͱΊ
    ໌շͳAPIΛઃܭ͢ΔͨΊͷ4ͭͷ໰͍
    APIͷ໾ׂɺ෭࡞༻͸͋Δ͔ɺ৘ใ͸଍Γ͍ͯΔ͔ɺ৑௕͞͸ͳ͍͔

    View Slide

  31. We are Hiring !!

    IUUQTFOHJOFFSBOEQBEDPKQ
    ΤϯδχΞ࠾༻

    View Slide


  32. ͋Γ͕ͱ͏͍͟͝·ͨ͠
    @jrsaruo_tech
    'PMMPXNF
    𝕏

    View Slide