Save 37% off PRO during our Black Friday Sale! »

Droidcon Berlin: Everything is an API

Fc78fd09b8fee61efd4ef003fe104eb6?s=47 Ash Davies
October 20, 2021

Droidcon Berlin: Everything is an API

When creating a new app module, or modularising an existing one, it becomes easy to forget who might be consuming it. It becomes easy to forget that every decision you make will affect how it is used, or in the worst case, abused. We're told that code should document itself, but how do these design decisions reflect in the understanding of intended use?

Just because we might not be exposing a module as a public or open-sourced library, doesn't mean we can't benefit from making good decisions towards an effective and sensible API. By taking the stance that every piece of code we write is an API we can build more versatile and scalable applications.

In this talk, I'll discuss how you can apply best practices from the open-source world to your project, to guard implementations, provide concise and specific contracts, practical documentation mechanisms, and how doing so can aid (or harm) your build time.

Fc78fd09b8fee61efd4ef003fe104eb6?s=128

Ash Davies

October 20, 2021
Tweet

Transcript

  1. Ash Davies Android & Kotlin GDE Berlin @askashdavies Everything is

    an API OMG IRL INORITE?! Droidcon Berlin - Oct 21’ 󰎲
  2. What is an API? Article Periodocal Incollection…? Accountable Property Inventory...?

    Acquisition Program Integration…? Academic Performance Index…? Asset Priority Index....? Annual Parasite Incidence…?
  3. Application Programming Interface noun A set of functions and procedures

    allowing the creation of applications that access the features or data of an operating system, application, or other service.
  4. Communication

  5. Language 🗣 󰎼 ¿Qué tal? 󰧻 Helô 󰏃 Salut! 󰐮

    Privet 󰏅 Hello! 󰏢 Ciao 󰎩 Nǐ hǎo 󰎲 Hallo 󰐨 Oi 󰎺 Ahlan 󰏮Anyoung 󰐴 Hej 󰏏 Yassou 󰑍 Selam
  6. Application Programming Interface Representational State Transfer Simple Object Access Protocol

    Remote Procedure Call Transactional Agreement Protocol Atomic Resource Translation Application Programming Interface
  7. APIs curl \ -H "Accept: application/vnd.github.v3+json" \ https://api.github.com/repos/octocat/hello-world/actions/artifacts What does

    an API look like?
  8. APIs { "total_count": 2, "artifacts": [ { "id": 11, "node_id":

    "MDg6QXJ0aWZhY3QxMQ==", "name": "Rails", "size_in_bytes": 556, "url": "https://api.github.com/repos/octo-org/octo-docs/actions/artifacts/11", "archive_download_url": "https://api.github.com/repos/octo-org/octo-docs/actions/artifacts/11/zip", "updated_at": "2020-02-21T14:59:22Z" } ] What does an API look like?
  9. • SOAP (XML) • RESTful (JSON) • GraphQL • gRPC

    (Proto) APIs Protocols Just a small slice...
  10. Hierarchy APIs

  11. Android API Council android.googlesource.com /platform/developers/docs /+/refs/heads/master /api-guidelines/index.md QR Codes? In

    2021? Srsly?
  12. Software Development Kit noun A set of tools for third-party

    developers to use in producing applications using a particular framework or platform. "the documentation and SDKs have already been updated to reflect the new capabilities"
  13. None
  14. ¯\_(ツ)_/¯

  15. • Increased learning curve • Longer to peer review •

    Unpleasant to resolve • Increased risk of bugs • Slowed feature delivery API Decisions Cost of Technical Debt
  16. “Debugging is like being the detective in a crime movie

    where you are also the murderer” - Filipe Fortes
  17. • Your code will always be consumed by other people

    • Technical debt is not often resolved or paid back • Have respect for your colleagues, make their lives easier • Test code should also be considered production ready API Decisions Double standards
  18. “Always code as if the [sic] guy who ends up

    maintaining your code will be a violent psychopath who knows where you live” - John Woods
  19. Good Code? 🏆

  20. • No such thing as perfect code • Perfect is

    the enemy of good • Perfect solution fallacy (Nirvana fallacy) • Problem for API maintainers • Done is ok, work on making it better Good Code?! 😭 Not so easy...
  21. “Dans ses écrits, un sage Italien, dit que le mieux

    est l'ennemi du bien” - Voltaire (François-Marie Arouet)
  22. • Keep your API surface as small as possible •

    Allow yourself room for change • Try not to expose behaviour Code Progressively Through abstraction...
  23. • Prefer interface contracts • Composition over inheritance • Interface

    segregation principle • Single responsibility principle Hiding Implementations... Through abstraction...
  24. • Javadoc can sometimes be useful if maintained • Code

    should always be self-documenting • Name considerably and with purpose • Consider sources of code smell Usefulness of Documentation “What’s a Javadoc?!”
  25. • Conditional statements • Iteration or recursion • Significant indentation

    • Polymorphism • Mutability Code Smell 👃 “My God! What is that smell?” - Veronica Corningstone
  26. “There are only two hard things in Computer Science: cache

    invalidation and naming things” - Phil Karlton
  27. Meaningful Names Naming is hard.

  28. Meaningful Naming for (i: Int in kS) { try {

    c.connect(i) } catch(e: Throwable) { // Meh 󰤇 } } Unclear purpose or intention
  29. Meaningful Naming for (index: Int in keySet) { try {

    client.connect(index) } catch(ignored: Throwable) { } } Unclear purpose or intention
  30. Meaningful Naming internal suspend infix fun String.contains(value: String): Boolean Signatures

  31. Meaningful Naming internal suspend infix fun String.contains(value: String): Boolean Signatures

    Method is visible only to members in the same package
  32. Meaningful Naming internal suspend infix fun String.contains(value: String): Boolean Signatures

    Method will return a result asynchronously, can only be accessed by coroutine or by another suspended method
  33. Meaningful Naming internal suspend infix fun String.contains(value: String): Boolean Signatures

    Method can be used with the Kotlin infix notation Eg. val result: Boolean = “12345” contains “234”
  34. Meaningful Naming internal suspend infix fun String.contains(value: String): Boolean Signatures

    Receiver indicates the scope of the function, must be called as an extension on this type
  35. Meaningful Naming internal suspend infix fun String.contains(value: String): Boolean Signatures

  36. Meaningful Naming internal suspend infix fun String.contains(value: String): Boolean Signatures

    Named parameters with type give us information about how to call the method
  37. Meaningful Naming internal suspend infix fun String.contains(value: String): Boolean Signatures

    Method return type tells us how to use the result
  38. Meaningful Naming fun updateClaimWithPolicyDetails(c: Claim, pc: PolicyCriteria, identifier: String) fun

    getIfNotSetWithDefault(value: Any): String fun compareAndSet(value: Any): Boolean fun isNullOrEmpty(value: String): Boolean Signatures
  39. Meaningful Naming public interface ViewStateFactory { /* ... */ }

    internal class ViewStateFactoryImpl { /* ... */ } Interfaces
  40. Impure Functions var values: MutableMap<Char, Int> = mutableMapOf('a' to 1)

    fun modify(items: MutableMap<Char, Int>): Int { val b: Int = 1; items['a'] = items['a'] * b + 2; return items['a']; } val c = modify(values);
  41. Interface Composition Prefer interface composition over inheritance • Inheritance forces

    the consumer to use a base class • Limitations on extending abstract classes • Potentially exposes protected behaviour • Prohibits Kotlin interface delegation
  42. Interface Abstraction public interface CoroutineScope { public val coroutineContext: CoroutineContext

    } internal class ContextScope(context: CoroutineContext) : CoroutineScope { override val coroutineContext: CoroutineContext = context } public fun CoroutineScope(context: CoroutineContext): CoroutineScope { return ContextScope(if (context[Job] != null) context else context + Job()) } Obfuscate behaviour through interface abstraction
  43. • Impact analysis, risk containment • Peer review scrutiny •

    Mob programming • Android API council • Guild meetings Democratise your API Decisions But not too much!
  44. The elephant in the room...

  45. Modularisation “Modularise all the things!”

  46. Modularisation Concurrency

  47. Modularisation Build Cache / Scan gradle.com

  48. Modularisation Pitfalls • Misaligned product flavours • Misbehaving dependencies •

    Incorrect configurations
  49. • Always a potential for risk • Make use of

    annotations! ◦ @Deprecated(message: String, replaceWith: ReplaceWith, level: DeprecationLevel) ◦ @RequiresOptIn(message: String, level: Level) ◦ @TechnicalDebt(issue: String, message: String) ◦ @VisibleForModularisation(otherwise: ProductionVisibility) But, we’re all human… 󰤇
  50. @Deprecated( message = "CoroutineScope.rxCompletable is deprecated in favour of top-level

    rxCompletable", level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("rxCompletable(context, block)") ) public fun CoroutineScope.rxCompletable( context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> Unit ): Completable = rxCompletableInternal(this, context, block) We’re all Human 󰤇 Migration Tools
  51. Half screen photo slide if text is necessary We’re all

    Human 󰤇 Decision Paralysis The worst decision is a decision not made in time.
  52. • code that documents itself? • code that can be

    changed easily? • easily and readily maintainable? • follows all the design principles? Conclusion Good code is...
  53. • code that documents itself? • code that can be

    changed easily? • easily and readily maintainable? • follows all the design principles? • code that can be easily deleted. Conclusion Good code is...
  54. “Every line of code is written without reason, maintained out

    of weakness, and deleted by chance” - Jean-Paul Sartre
  55. • Explicit mode for library authoring · Issue #45 ·

    Kotlin/KEEP • TwoHardThings • The Annotated Programmer - Pointer IO • Developers: Your Poorly Named Variables Are Hurting Your Team • How modularization can speed up your Android app's built time • Stefan Tilkov on Twitter: "Many enterprise IT departments have become big fans of an “API-first“ strategy" • The Human Cost of Tech Debt • Unreachable State Everything is an API Further Reading
  56. • Monkey User (monkeyuser.com) • Untitled Goose Game (goose.game) Everything

    is an API Easter Eggs
  57. Ash Davies Android & Kotlin GDE Berlin @askashdavies Thanks!