Schema Negotiation
Paul Frazee // Bluesky
TCP
HTTP
JSON
???
TCP
HTTP
JSON
???
???
FLEXIBLE
CORRECT
INTENT
RESULT
INTENT
RESULT
VIOLATION
{
"type": "tweet",
"media": ["sock.jpg"]
}
{
"type": "tweet",
"media": ["sock.jpg"],
"status": "picture-of-the-day"
}
{
"type": "tweet",
"media": ["sock.jpg"],
"status": "picture-of-the-day"
}
{
"type": "tweet",
"media": ["sock.jpg"],
"status": "picture-of-the-day"
}
INTENT
{
"type": "tweet",
"media": ["sock.jpg"],
"category": "sock-pictures"
}
INTENT
{
"type": "tweet",
"media": ["sock.jpg"],
"contentWarning": "dirty-socks"
}
INTENT
{
"type": "tweet",
"media": ["sock.jpg"],
"to": "bob@mail.com",
"cc": "sock-lovers@mail.com"
}
INTENT
{
"type": "tweet",
"media": ["sock.jpg"],
"to": "bob@mail.com",
"cc": "sock-lovers@mail.com"
}
INTENT
CONTRACT
1
Schema is a contract
interface Post {
text: string,
media: string[]
}
interface Post {
text: string,
media: string[]
}
V1
interface Post {
text: string,
media: string[]
}
V1
interface Post {
text: string,
media: MediaEmbed[]
}
interface Post {
text: string,
media: string[]
}
V1
interface Post {
text: string,
media: MediaEmbed[]
}
V2
interface Post {
text: string,
media: string[]
}
V1
interface Post {
text: string,
media: MediaEmbed[]
}
V2
interface Post {
text: string,
media: string[]
}
V1
interface Post {
text: string,
media: MediaEmbed[]
}
V2
interface Post {
text: string,
media: string[]
}
V1
interface Post {
text: string,
media:
(string|MediaEmbed)[]
}
V2
interface Post {
text: string,
media: string[]
}
V1
interface Post {
text: string,
media:
(string|MediaEmbed)[]
}
V2
interface Post {
text: string,
media: string[]
}
V1
interface Post {
text: string,
media: string[],
mediaExt?: MediaEmbed[]
}
V2
1
Schema is a contract
2
Minor revisions only
SCHEMA NEGOTIATION
SUPPORTED SCHEMAS
REQUIRED SCHEMAS
Consumer
Provider
I understand
POST
POSTv2
COMMENT
"
"
I understand
POST
POSTv2
COMMENT
"
"
{..}
.json
POSTv2
I understand
POST
POSTv2
COMMENT
"
"
{..}
.json
POSTv2
Base
Type
I understand
POST
POSTv2
COMMENT
"
"
{..}
.json
POSTv2
Extension Type
I understand
POST
POSTv2
COMMENT
"
"
{..}
.json
POSTv2
I understand
POST
POSTv2
COMMENT
StatusUpdate
"
"
{..}
.json
POSTv2
I understand
POST
POSTv2
COMMENT
StatusUpdate
"
"
{..}
.json
POSTv2
I understand
POST
POSTv2
COMMENT
"
"
{..}
.json
POSTv2
I understand
POST
POSTv2
COMMENT
"
"
{..}
.json
POSTv2
Fallback: IGNORE
I understand
POST
POSTv2
COMMENT
"
"
{..}
.json
POSTv2
Fallback: WARN
I understand
POST
POSTv2
COMMENT
"
"
{..}
.json
POSTv2
Fallback: ERROR
SCHEMA NEGOTIATION
SUPPORTED SCHEMAS
REQUIRED SCHEMAS
Consumer
Provider
v = createValidator({
base: ['Post', 'Post.v2', 'Comment'],
ext: ['StatusUpdate']
})
DECLARE SUPPORT
VALIDATE RECORD
res = v.validate({
type: 'Post',
text: 'Hello, world!'
})
v = createValidator({
base: ['Post', 'Post.v2', 'Comment'],
ext: ['StatusUpdate']
})
SUPPORTED? YES
res = v.validate({
type: 'Post',
text: 'Hello, world!'
})
res.supported == true
v = createValidator({
base: ['Post', 'Post.v2', 'Comment'],
ext: ['StatusUpdate']
})
VALID? YES
res = v.validate({
type: 'Post',
text: 'Hello, world!'
})
res.supported == true
res.valid == true
v = createValidator({
base: ['Post', 'Post.v2', 'Comment'],
ext: ['StatusUpdate']
})
VALID? NO
res = v.validate({
type: 'Post',
text: 12345
})
res.supported == true
res.valid == false
v = createValidator({
base: ['Post', 'Post.v2', 'Comment'],
ext: ['StatusUpdate']
})
SUPPORTED? NO
res = v.validate({
type: 'OtherPost',
text: 'Hello World'
})
res.supported == false
res.valid == undefined
v = createValidator({
base: ['Post', 'Post.v2', 'Comment'],
ext: ['StatusUpdate']
})
EXTENSION
res = v.validate({
type: 'Post',
text: 'Hello World',
ext: {
type: 'StatusUpdate',
value: 'picture-of-the-day'
}
})
v = createValidator({
base: ['Post', 'Post.v2', 'Comment'],
ext: ['StatusUpdate']
})
SUPPORTED? YES
res = v.validate({
type: 'Post',
text: 'Hello World',
ext: {
type: 'StatusUpdate',
value: 'picture-of-the-day'
}
})
v = createValidator({
base: ['Post', 'Post.v2', 'Comment'],
ext: ['StatusUpdate']
})
SUPPORTED? NO BUT IGNORE
res = v.validate({
type: 'Post',
text: 'Hello World',
ext: {
type: 'Poll',
question: 'A or B?'
}
})
v = createValidator({
base: ['Post', 'Post.v2', 'Comment'],
ext: ['StatusUpdate']
})
SUPPORTED? NO, WARN
res = v.validate({
type: 'Post',
text: 'Hello World',
ext: {
type: 'Poll',
question: 'A or B?',
fallback: 'This post contains a poll…'
}
})
v = createValidator({
base: ['Post', 'Post.v2', 'Comment'],
ext: ['StatusUpdate']
})
SUPPORTED? NO, FAIL
res = v.validate({
type: 'Post',
text: 'Hello World',
ext: {
type: 'Poll',
question: 'A or B?',
required: true
}
})
v = createValidator({
base: ['Post', 'Post.v2', 'Comment'],
ext: ['StatusUpdate']
})
1
Schema is a contract
2
Minor revisions only
3
Extend by negotiation
(WIP)
Thanks!
Paul Frazee // Bluesky