Slide 1

Slide 1 text

Everything is an API Kotlin User Group Berlin - Mai 23’ 󰎲 Ash Davies Android / Kotlin GDE - Berlin [email protected]

Slide 2

Slide 2 text

What is an API? Article Periodocal Incollection…? Accountable Property Inventory...? Acquisition Program Integration…? Academic Performance Index…? Asset Priority Index....? Annual Parasite Incidence…?

Slide 3

Slide 3 text

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.

Slide 4

Slide 4 text

Communication

Slide 5

Slide 5 text

Language 🗣 󰎼 ¿Qué tal? 󰧻 Helô 󰏃 Salut! 󰑒 Pryvit 󰏅 Hello! 󰏢 Ciao 󰎩 Nǐ hǎo 󰎲 Hallo 󰐨 Oi 󰎺 Ahlan 󰏮Anyoung 󰐴 Hej 󰏏 Yassou 󰑍 Selam

Slide 6

Slide 6 text

Application Programming Interface Representational State Transfer Simple Object Access Protocol Remote Procedure Call Transactional Agreement Protocol Atomic Resource Translation Application Programming Interface

Slide 7

Slide 7 text

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?

Slide 8

Slide 8 text

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?

Slide 9

Slide 9 text

● SOAP (XML) ● RESTful (JSON) ● GraphQL ● gRPC (Proto) APIs Protocols Just a small slice... monkeyuser.com

Slide 10

Slide 10 text

Hierarchy APIs

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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"

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

¯\_(ツ)_/¯

Slide 15

Slide 15 text

● Increased learning curve ● Longer to peer review ● Unpleasant to resolve ● Increased risk of bugs ● Slowed feature delivery API Decisions Cost of Technical Debt

Slide 16

Slide 16 text

“Debugging is like being the detective in a crime movie where you are also the murderer” - Filipe Fortes

Slide 17

Slide 17 text

● 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

Slide 18

Slide 18 text

“Always code as if the guy [sic] who ends up maintaining your code will be a violent psychopath who knows where you live” - John Woods

Slide 19

Slide 19 text

Good Code? 🏆

Slide 20

Slide 20 text

● 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...

Slide 21

Slide 21 text

“Dans ses écrits, un sage Italien, dit que le mieux est l'ennemi du bien” - Voltaire (François-Marie Arouet)

Slide 22

Slide 22 text

● Keep your API surface as small as possible ● Allow yourself room for change ● Try not to expose behaviour Code Progressively Through abstraction...

Slide 23

Slide 23 text

● Prefer interface contracts ● Composition over inheritance ● Interface segregation principle ● Single responsibility principle Hiding Implementations... Through abstraction...

Slide 24

Slide 24 text

● 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?!”

Slide 25

Slide 25 text

● Conditional statements ● Iteration or recursion ● Polymorphism ● Mutability ● Significant indentation Code Smell 👃 “My God! What is that smell?” - Veronica Corningstone

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

“There are only two hard things in Computer Science: cache invalidation and naming things” - Phil Karlton

Slide 28

Slide 28 text

Meaningful Names Naming is hard.

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

Meaningful Naming for (index: Int in keySet) { try { client.connect(index) } catch (ignored: Throwable) { } } Unclear purpose or intention

Slide 31

Slide 31 text

Meaningful Naming for (index: Int in keySet) { try { client.connect(index) } catch (ignored: IndexOutOfBoundsException) { } } Unclear purpose or intention

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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”

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

Meaningful Naming internal suspend infix fun String.contains(value: String): Boolean Signatures Method return type tells us how to use the result

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

Meaningful Naming public interface ViewStateFactory { /* ... */ } internal class ViewStateFactoryImpl { /* ... */ } Interfaces

Slide 42

Slide 42 text

Impure Functions var values: MutableMap = mutableMapOf('a' to 1) fun modify(items: MutableMap): Int { val b: Int = 1; items['a'] = items['a'] * b + 2; return items['a']; } val c = modify(values);

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

Impact analysis, risk containment Peer review scrutiny Mob programming Android API council Guild meetings Democratise your API Decisions But not too much!

Slide 46

Slide 46 text

The elephant in the room...

Slide 47

Slide 47 text

Modularisation “Modularise all the things!”

Slide 48

Slide 48 text

Modularisation Concurrency

Slide 49

Slide 49 text

Modularisation Build Cache / Scan gradle.com

Slide 50

Slide 50 text

Modularisation Pitfalls ● Misaligned product flavours ● Misbehaving dependencies ● Incorrect configurations

Slide 51

Slide 51 text

● 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… 󰤇

Slide 52

Slide 52 text

@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

Slide 53

Slide 53 text

Decision-Making Hype Driven Development [email protected]

Slide 54

Slide 54 text

Half screen photo slide if text is necessary We’re all Human 󰤇 Decision Paralysis The worst decision is a decision not made in time.

Slide 55

Slide 55 text

● Code that documents itself? ● Code that can be changed easily? ● Easily and readily maintainable? ● Follows all the design principles? Conclusion Good code is...

Slide 56

Slide 56 text

● 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...

Slide 57

Slide 57 text

“Every existing thing is born without reason, prolongs itself out of weakness and dies by chance.” - Jean-Paul Sartre

Slide 58

Slide 58 text

“Every line of code is written without reason, maintained out of weakness, and deleted by chance” - Jean-Paul Sartre

Slide 59

Slide 59 text

Explicit mode for library authors (Kotlin) TwoHardThing (Martin Fowler) The Annotated Programmer (Chet Haase) Developers: Your Poorly Named Variables Are Hurting Your Team (Bennett Garner) How modularization can speed up your Android app's built tim (Nikita Kozlov) Stefan Tilkov on Twitter: "Many enterprise IT departments have become big fans of an “API-first“ strategy" The Human Cost of Tech Deb (Erik Dietrich) Everything is an API Further Reading

Slide 60

Slide 60 text

Thanks! Ash Davies - Cat Person Android / Kotlin GDE - Berlin [email protected]