SlideShare a Scribd company logo
1 of 36
Building a friendly Kotlin SDK to
connect to JetBrains Space
Maarten Balliauw
@maartenballiauw
Agenda
JetBrains Space
JetBrains Space HTTP API
Building a Kotlin SDK for the Space HTTP API
Code generation
Developer experience
JetBrains Space
JetBrains Space
Integrated Team Environment
https://jetbrains.space
People
Teams
Projects
-
Workspaces
for teams
Collaboration
JetBrains Space
demo
The Space HTTP API
Integrated Team Environment
More information in Space == more value from Space
Internal integrations out of the box
Vacation shown in profile
Blog post targeted to team/location
Calendar integration in blog post
Everything can be a ToDo item
...
What with external integrations? Extensibility?
Everything as an HTTP API!
What do you want to build? Which integration do you need?
Import data
Post to chat
Manage users, teams, and locations programatically
Build dashboards
???
“Open up everything”
Large HTTP API surface...
HTTP API Playground to explore!
HTTP API Playground
demo
$fields
Top-level fields returned by default
Unless $fields query parameter used
Use $fields to be specific, or get nested fields
$fields=id,icon,name
$fields=id,name,boards(id,description)
$fields=id,name,boards(id,info(columns))
$fields=*,boards(id,description)
Building a Kotlin SDK
for the Space HTTP API
Hello, Kotlin! 👋
Goal: make our users succesful at using Space in their team/organization
Provide a ready-to-use SDK
Minimal configuration needed
Discoverability
TL;DR: Lead integration developers on the shortest path to success
How? Handcrafted
No.
Over 150 API endpoints
Over 700 object types
Churn during Space EAP / Space Beta
How? OpenAPI?
Use openapi-generator, generate based on OpenAPI / Swagger document
Some incompatible object types needed custom code generation
How? Custom code generation
Space exposes HTTP API Model
Enumerations
DTOs (objects passed around)
Resources
+ data types, nullability,
default values, ...
https://your.jetbrains.space/api/http/http-api-model?$fields=dto,enums,urlParams,resources(*,nestedResources!)
Enumeration model
class HA_Enum(
val id: TID,
val name: String,
val values: List<String>,
val deprecation: HA_Deprecation?
)
data class HA_Deprecation(
val message: String,
val since: String,
val forRemoval: Boolean
)
Enumeration code generator
fun visit(enumType: HA_Enum) = buildString {
enumType.deprecation?.let {
appendLine("@Deprecated(message = "${it.message}") }
val enumClassName = enumType.name.kotlinClassNameJoined()
appendLine("enum class $enumClassName {")
enumType.values.forEach {
appendLine("$it,")
}
appendLine("}")
}
enum class AbsenceListMode {
All,
WithAccessibleReasonUnapproved,
WithAccessibleReasonAll
}
DTO model
class HA_Dto(
val id: TID,
val name: String,
val fields: List<HA_DtoField>,
val hierarchyRole: HierarchyRole,
val extends: Ref?,
val implements: List<Ref>,
val inheritors: List<Ref>,
val deprecation: HA_Deprecation?,
val record: Boolean
)
class HA_DtoField(val field: HA_Field, val extension: Boolean)
data class HA_Field(
val name: String,
val type: HA_Type,
val deprecation: HA_Deprecation?,
val optional: Boolean,
val defaultValue: HA_DefaultValue?
)
Endpoints model
Endpoint id, name, base path
Resource id, name, path, parameters
Resource id, name, path, parameters
Resource id, name, path, parameters
...
+ parameter types
+ return types
+ default values (const, variable)
Custom code generation
demo
Strings? KotlinPoet?
Generally, a few ways to generate code:
String-based
Write strings directly
Use a template engine
Easy to recognize what gets written
Model-based
KotlinPoet https://square.github.io/kotlinpoet/
Safety (e.g. can’t forget to write class name)
KotlinPoet
Kotlin and Java API for generating .kt source files
Ensures all properties of code are in place (modifier, type name, ...)
Callable references
Formatting of generated code
https://square.github.io/kotlinpoet/
FunSpec.builder("main")
.addStatement("val helloWorld = %L", helloFunction.reference())
.build()
Extension functions everywhere
Many places where we need:
Kotlin class name from string
Kotlin classs from Space model type (Enum/DTO/URL parameter/...)
fun String.kotlinClassName(): List<String> = split(".")
fun HA_Dto.getClassName() =
ClassName("space.jetbrains.api.runtime.types", name.kotlinClassName())
fun HA_UrlParameterOption.getClassName() =
ClassName("space.jetbrains.api.runtime.types", optionName.kotlinClassName())
Developer experience
The ideal “Getting started”
1. Register application in Space
2. Add to Gradle file
dependencies {
implementation "org.jetbrains:space-sdk-jvm:$space_version"
}
3. Create connection
val spaceClient = SpaceHttpClient(HttpClient())
.withServiceAccountTokenSource(
"client-id",
"client-secret",
"https://your.jetbrains.space/")
4. Profit!
Large API surface
Remember $fields ?
Top-level fields returned by default
Unless $fields query parameter used
Use $fields to be specific, or get nested fields
$fields
Top-level fields by default, partial builder to be specific
val memberProfile = spaceClient.teamDirectory.profiles
.getProfile(ProfileIdentifier.Username("Heather.Stewart"))
val memberProfile = spaceClient.teamDirectory.profiles
.getProfile(ProfileIdentifier.Username("Heather.Stewart")) {
defaultPartial() // with all top level fields
managers { // include managers
id() // with their id
username() // and their username
name { // and their name
firstName() // with firstName
lastName() // and firstName
}
}
}
API playground
Building a chat message...
spaceClient.chats.messages.sendMessage(
recipient = MessageRecipient.Channel(ChatChannel.FromName(chatChannelName)),
content = ChatMessage.Block(
style = MessageStyle.SUCCESS,
outline = MessageOutline(icon = null, text = "Have you tried JetBrains Space?"),
sections = listOf(
MessageSection(
header = "JetBrains Space",
elements = listOf(
MessageText(accessory = MessageIcon(ApiIcon("space"), MessageStyle.SUCCESS),
content = "JetBrains Space is an Integrated Team Environment."),
MessageText(accessory = null, content = "Have you tried JetBrains Space?"),
MessageDivider,
MessageText(accessory = null, content = "Get access at https://www.jetbrains.com/space/")
),
footer = "Check it out at https://www.jetbrains.com/space/"
)
),
messageData = null
),
unfurlLinks = false
)
spaceClient.chats.messages.sendMessage(
recipient = MessageRecipient.Channel(ChatChannel.FromName(chatChannelName)),
content = message {
style = MessageStyle.SUCCESS
outline = MessageOutline(icon = null, text = "Have you tried JetBrains Space?")
section {
header = "JetBrains Space"
textWithIcon("JetBrains Space is an Integrated Team Environment.", "space",
MessageStyle.SUCCESS)
text("Have you tried JetBrains Space?")
divider()
text("Get access at https://www.jetbrains.com/space/")
footer = "Check it out at https://www.jetbrains.com/space/"
}
},
unfurlLinks = false
)
Building a chat message...
Identifiers and factory methods
Developer experience
demo
Conclusion
Conclusion
JetBrains Space is an Integrated Team Environment
JetBrains Space HTTP API exposes everything
Building a Kotlin SDK for the Space HTTP API
Goal: make our users succesful at using Space
Provide a ready-to-use SDK
Minimal configuration needed
Discoverability
Code generation
Focus on developer experience
Thank you!
https://blog.maartenballiauw.be
@maartenballiauw

More Related Content

More from Maarten Balliauw

CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...
CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...
CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...Maarten Balliauw
 
NDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and Search
NDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and SearchNDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and Search
NDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and SearchMaarten Balliauw
 
Approaches for application request throttling - Cloud Developer Days Poland
Approaches for application request throttling - Cloud Developer Days PolandApproaches for application request throttling - Cloud Developer Days Poland
Approaches for application request throttling - Cloud Developer Days PolandMaarten Balliauw
 
Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...
Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...
Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...Maarten Balliauw
 
Approaches for application request throttling - dotNetCologne
Approaches for application request throttling - dotNetCologneApproaches for application request throttling - dotNetCologne
Approaches for application request throttling - dotNetCologneMaarten Balliauw
 
CodeStock - Exploring .NET memory management - a trip down memory lane
CodeStock - Exploring .NET memory management - a trip down memory laneCodeStock - Exploring .NET memory management - a trip down memory lane
CodeStock - Exploring .NET memory management - a trip down memory laneMaarten Balliauw
 
ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...
ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...
ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...Maarten Balliauw
 
ConFoo Montreal - Approaches for application request throttling
ConFoo Montreal - Approaches for application request throttlingConFoo Montreal - Approaches for application request throttling
ConFoo Montreal - Approaches for application request throttlingMaarten Balliauw
 
Microservices for building an IDE – The innards of JetBrains Rider - TechDays...
Microservices for building an IDE – The innards of JetBrains Rider - TechDays...Microservices for building an IDE – The innards of JetBrains Rider - TechDays...
Microservices for building an IDE – The innards of JetBrains Rider - TechDays...Maarten Balliauw
 
JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...
JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...
JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...Maarten Balliauw
 
DotNetFest - Let’s refresh our memory! Memory management in .NET
DotNetFest - Let’s refresh our memory! Memory management in .NETDotNetFest - Let’s refresh our memory! Memory management in .NET
DotNetFest - Let’s refresh our memory! Memory management in .NETMaarten Balliauw
 
VISUG - Approaches for application request throttling
VISUG - Approaches for application request throttlingVISUG - Approaches for application request throttling
VISUG - Approaches for application request throttlingMaarten Balliauw
 
What is going on - Application diagnostics on Azure - TechDays Finland
What is going on - Application diagnostics on Azure - TechDays FinlandWhat is going on - Application diagnostics on Azure - TechDays Finland
What is going on - Application diagnostics on Azure - TechDays FinlandMaarten Balliauw
 
ConFoo - Exploring .NET’s memory management – a trip down memory lane
ConFoo - Exploring .NET’s memory management – a trip down memory laneConFoo - Exploring .NET’s memory management – a trip down memory lane
ConFoo - Exploring .NET’s memory management – a trip down memory laneMaarten Balliauw
 
ConFoo - NuGet beyond Hello World
ConFoo - NuGet beyond Hello WorldConFoo - NuGet beyond Hello World
ConFoo - NuGet beyond Hello WorldMaarten Balliauw
 
Approaches to application request throttling
Approaches to application request throttlingApproaches to application request throttling
Approaches to application request throttlingMaarten Balliauw
 
NuGet beyond Hello World - DotNext Piter 2017
NuGet beyond Hello World - DotNext Piter 2017NuGet beyond Hello World - DotNext Piter 2017
NuGet beyond Hello World - DotNext Piter 2017Maarten Balliauw
 
Exploring .NET memory management (iSense)
Exploring .NET memory management (iSense)Exploring .NET memory management (iSense)
Exploring .NET memory management (iSense)Maarten Balliauw
 
Exploring .NET memory management - JetBrains webinar
Exploring .NET memory management - JetBrains webinarExploring .NET memory management - JetBrains webinar
Exploring .NET memory management - JetBrains webinarMaarten Balliauw
 
DNS for Developers - ConFoo Montreal
DNS for Developers - ConFoo MontrealDNS for Developers - ConFoo Montreal
DNS for Developers - ConFoo MontrealMaarten Balliauw
 

More from Maarten Balliauw (20)

CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...
CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...
CloudBurst 2019 - Indexing and searching NuGet.org with Azure Functions and S...
 
NDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and Search
NDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and SearchNDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and Search
NDC Oslo 2019 - Indexing and searching NuGet.org with Azure Functions and Search
 
Approaches for application request throttling - Cloud Developer Days Poland
Approaches for application request throttling - Cloud Developer Days PolandApproaches for application request throttling - Cloud Developer Days Poland
Approaches for application request throttling - Cloud Developer Days Poland
 
Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...
Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...
Indexing and searching NuGet.org with Azure Functions and Search - Cloud Deve...
 
Approaches for application request throttling - dotNetCologne
Approaches for application request throttling - dotNetCologneApproaches for application request throttling - dotNetCologne
Approaches for application request throttling - dotNetCologne
 
CodeStock - Exploring .NET memory management - a trip down memory lane
CodeStock - Exploring .NET memory management - a trip down memory laneCodeStock - Exploring .NET memory management - a trip down memory lane
CodeStock - Exploring .NET memory management - a trip down memory lane
 
ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...
ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...
ConFoo Montreal - Microservices for building an IDE - The innards of JetBrain...
 
ConFoo Montreal - Approaches for application request throttling
ConFoo Montreal - Approaches for application request throttlingConFoo Montreal - Approaches for application request throttling
ConFoo Montreal - Approaches for application request throttling
 
Microservices for building an IDE – The innards of JetBrains Rider - TechDays...
Microservices for building an IDE – The innards of JetBrains Rider - TechDays...Microservices for building an IDE – The innards of JetBrains Rider - TechDays...
Microservices for building an IDE – The innards of JetBrains Rider - TechDays...
 
JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...
JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...
JetBrains Day Seoul - Exploring .NET’s memory management – a trip down memory...
 
DotNetFest - Let’s refresh our memory! Memory management in .NET
DotNetFest - Let’s refresh our memory! Memory management in .NETDotNetFest - Let’s refresh our memory! Memory management in .NET
DotNetFest - Let’s refresh our memory! Memory management in .NET
 
VISUG - Approaches for application request throttling
VISUG - Approaches for application request throttlingVISUG - Approaches for application request throttling
VISUG - Approaches for application request throttling
 
What is going on - Application diagnostics on Azure - TechDays Finland
What is going on - Application diagnostics on Azure - TechDays FinlandWhat is going on - Application diagnostics on Azure - TechDays Finland
What is going on - Application diagnostics on Azure - TechDays Finland
 
ConFoo - Exploring .NET’s memory management – a trip down memory lane
ConFoo - Exploring .NET’s memory management – a trip down memory laneConFoo - Exploring .NET’s memory management – a trip down memory lane
ConFoo - Exploring .NET’s memory management – a trip down memory lane
 
ConFoo - NuGet beyond Hello World
ConFoo - NuGet beyond Hello WorldConFoo - NuGet beyond Hello World
ConFoo - NuGet beyond Hello World
 
Approaches to application request throttling
Approaches to application request throttlingApproaches to application request throttling
Approaches to application request throttling
 
NuGet beyond Hello World - DotNext Piter 2017
NuGet beyond Hello World - DotNext Piter 2017NuGet beyond Hello World - DotNext Piter 2017
NuGet beyond Hello World - DotNext Piter 2017
 
Exploring .NET memory management (iSense)
Exploring .NET memory management (iSense)Exploring .NET memory management (iSense)
Exploring .NET memory management (iSense)
 
Exploring .NET memory management - JetBrains webinar
Exploring .NET memory management - JetBrains webinarExploring .NET memory management - JetBrains webinar
Exploring .NET memory management - JetBrains webinar
 
DNS for Developers - ConFoo Montreal
DNS for Developers - ConFoo MontrealDNS for Developers - ConFoo Montreal
DNS for Developers - ConFoo Montreal
 

Recently uploaded

SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 

Recently uploaded (20)

SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 

Building a friendly Kotlin SDK to connect to JetBrains Space

  • 1. Building a friendly Kotlin SDK to connect to JetBrains Space Maarten Balliauw @maartenballiauw
  • 2. Agenda JetBrains Space JetBrains Space HTTP API Building a Kotlin SDK for the Space HTTP API Code generation Developer experience
  • 4. JetBrains Space Integrated Team Environment https://jetbrains.space People Teams Projects - Workspaces for teams Collaboration
  • 7. Integrated Team Environment More information in Space == more value from Space Internal integrations out of the box Vacation shown in profile Blog post targeted to team/location Calendar integration in blog post Everything can be a ToDo item ... What with external integrations? Extensibility?
  • 8. Everything as an HTTP API! What do you want to build? Which integration do you need? Import data Post to chat Manage users, teams, and locations programatically Build dashboards ??? “Open up everything” Large HTTP API surface... HTTP API Playground to explore!
  • 10. $fields Top-level fields returned by default Unless $fields query parameter used Use $fields to be specific, or get nested fields $fields=id,icon,name $fields=id,name,boards(id,description) $fields=id,name,boards(id,info(columns)) $fields=*,boards(id,description)
  • 11. Building a Kotlin SDK for the Space HTTP API
  • 12. Hello, Kotlin! 👋 Goal: make our users succesful at using Space in their team/organization Provide a ready-to-use SDK Minimal configuration needed Discoverability TL;DR: Lead integration developers on the shortest path to success
  • 13. How? Handcrafted No. Over 150 API endpoints Over 700 object types Churn during Space EAP / Space Beta
  • 14. How? OpenAPI? Use openapi-generator, generate based on OpenAPI / Swagger document Some incompatible object types needed custom code generation
  • 15. How? Custom code generation Space exposes HTTP API Model Enumerations DTOs (objects passed around) Resources + data types, nullability, default values, ... https://your.jetbrains.space/api/http/http-api-model?$fields=dto,enums,urlParams,resources(*,nestedResources!)
  • 16. Enumeration model class HA_Enum( val id: TID, val name: String, val values: List<String>, val deprecation: HA_Deprecation? ) data class HA_Deprecation( val message: String, val since: String, val forRemoval: Boolean )
  • 17. Enumeration code generator fun visit(enumType: HA_Enum) = buildString { enumType.deprecation?.let { appendLine("@Deprecated(message = "${it.message}") } val enumClassName = enumType.name.kotlinClassNameJoined() appendLine("enum class $enumClassName {") enumType.values.forEach { appendLine("$it,") } appendLine("}") } enum class AbsenceListMode { All, WithAccessibleReasonUnapproved, WithAccessibleReasonAll }
  • 18. DTO model class HA_Dto( val id: TID, val name: String, val fields: List<HA_DtoField>, val hierarchyRole: HierarchyRole, val extends: Ref?, val implements: List<Ref>, val inheritors: List<Ref>, val deprecation: HA_Deprecation?, val record: Boolean ) class HA_DtoField(val field: HA_Field, val extension: Boolean) data class HA_Field( val name: String, val type: HA_Type, val deprecation: HA_Deprecation?, val optional: Boolean, val defaultValue: HA_DefaultValue? )
  • 19. Endpoints model Endpoint id, name, base path Resource id, name, path, parameters Resource id, name, path, parameters Resource id, name, path, parameters ... + parameter types + return types + default values (const, variable)
  • 21. Strings? KotlinPoet? Generally, a few ways to generate code: String-based Write strings directly Use a template engine Easy to recognize what gets written Model-based KotlinPoet https://square.github.io/kotlinpoet/ Safety (e.g. can’t forget to write class name)
  • 22. KotlinPoet Kotlin and Java API for generating .kt source files Ensures all properties of code are in place (modifier, type name, ...) Callable references Formatting of generated code https://square.github.io/kotlinpoet/ FunSpec.builder("main") .addStatement("val helloWorld = %L", helloFunction.reference()) .build()
  • 23. Extension functions everywhere Many places where we need: Kotlin class name from string Kotlin classs from Space model type (Enum/DTO/URL parameter/...) fun String.kotlinClassName(): List<String> = split(".") fun HA_Dto.getClassName() = ClassName("space.jetbrains.api.runtime.types", name.kotlinClassName()) fun HA_UrlParameterOption.getClassName() = ClassName("space.jetbrains.api.runtime.types", optionName.kotlinClassName())
  • 25. The ideal “Getting started” 1. Register application in Space 2. Add to Gradle file dependencies { implementation "org.jetbrains:space-sdk-jvm:$space_version" } 3. Create connection val spaceClient = SpaceHttpClient(HttpClient()) .withServiceAccountTokenSource( "client-id", "client-secret", "https://your.jetbrains.space/") 4. Profit!
  • 27. Remember $fields ? Top-level fields returned by default Unless $fields query parameter used Use $fields to be specific, or get nested fields
  • 28. $fields Top-level fields by default, partial builder to be specific val memberProfile = spaceClient.teamDirectory.profiles .getProfile(ProfileIdentifier.Username("Heather.Stewart")) val memberProfile = spaceClient.teamDirectory.profiles .getProfile(ProfileIdentifier.Username("Heather.Stewart")) { defaultPartial() // with all top level fields managers { // include managers id() // with their id username() // and their username name { // and their name firstName() // with firstName lastName() // and firstName } } }
  • 30. Building a chat message... spaceClient.chats.messages.sendMessage( recipient = MessageRecipient.Channel(ChatChannel.FromName(chatChannelName)), content = ChatMessage.Block( style = MessageStyle.SUCCESS, outline = MessageOutline(icon = null, text = "Have you tried JetBrains Space?"), sections = listOf( MessageSection( header = "JetBrains Space", elements = listOf( MessageText(accessory = MessageIcon(ApiIcon("space"), MessageStyle.SUCCESS), content = "JetBrains Space is an Integrated Team Environment."), MessageText(accessory = null, content = "Have you tried JetBrains Space?"), MessageDivider, MessageText(accessory = null, content = "Get access at https://www.jetbrains.com/space/") ), footer = "Check it out at https://www.jetbrains.com/space/" ) ), messageData = null ), unfurlLinks = false )
  • 31. spaceClient.chats.messages.sendMessage( recipient = MessageRecipient.Channel(ChatChannel.FromName(chatChannelName)), content = message { style = MessageStyle.SUCCESS outline = MessageOutline(icon = null, text = "Have you tried JetBrains Space?") section { header = "JetBrains Space" textWithIcon("JetBrains Space is an Integrated Team Environment.", "space", MessageStyle.SUCCESS) text("Have you tried JetBrains Space?") divider() text("Get access at https://www.jetbrains.com/space/") footer = "Check it out at https://www.jetbrains.com/space/" } }, unfurlLinks = false ) Building a chat message...
  • 35. Conclusion JetBrains Space is an Integrated Team Environment JetBrains Space HTTP API exposes everything Building a Kotlin SDK for the Space HTTP API Goal: make our users succesful at using Space Provide a ready-to-use SDK Minimal configuration needed Discoverability Code generation Focus on developer experience

Editor's Notes

  1. https://pixabay.com
  2. Clear cookies and auth in demo.jetbrains.space! Setup everything to work with demo.jetbrains.space space-api-client, space-api-client-samples, and space-app-tutorials open in IJ
  3. Show home page and mention what is shown (relevat info for me) Show project, mention repo’s, issues, checklists, ... Always possible to annotate and ask questions inline in code. Other folks will see this pop up in chat, so they do not necesarily have to switch context if it’s a minor question. Mention issues, and again, chat integration. Everything can be a to-do as well, use the lightning bolt icon. Automation/CI integrated. Absences integrated is where things get interesting. Who should I contact for certain responsibility? Is that other perso naround to look at my code review? Blogs. Organization-wide, for specific teams or locations. E.g. To share post-mortems, or team announcements, without overloading others. Again, relevant infomation to you. Many other things such as a knowledge base, artifact repo’s for NuGet, NPM, Docker, ...
  4. Show HTTP API playground, send a chat message or something like that. Or get profile info. Mention different endpoints, API’s grouped by functionality Mention request builder, all that, easy to reproduce Show getting a profile, selecting properties, and highlight $fields
  5. Show space-api-client API model classes, show: HA_Enum, HA_Dto, HierarchyRole enumeration Show Main.kt to see how it is bootstrapped Show space/jetbrains/api/generator/GenerateTypes.kt:44 Using KotlinPoet (more on that later) Show the extension methods, like kotlinClassNameJoined() and annotationSpecs.deprecation
  6. KotlinPoet in Kotlin SDK
  7. Show space-api-client-samples Show connection setup Show using team directory Get profiles with their name – explain $fields here. No partial -> get top level Partial -> specific, but has code completion Show exception case where we help you out (unknown property accessor) Chat: show message builder DSL Show identifiers with chat