Episode Transcript
Transcripts are displayed as originally observed. Some content, including advertisements may have changed.
Use Ctrl + F to search
0:05
Welcome to Fall Through, your source for
0:07
deep conversations about technology, software, and computing. I'm
0:10
your host, Chris Brando, also known scriptable, and
0:12
on today's episode, we are talking about API
0:14
design. We'll talk about things like having a
0:16
theory of your API, how to build a
0:19
foundation for it, and how to get into
0:21
the trenches and actually start building it. And
0:23
at the end, we also have some insight
0:26
into how we make this podcast. So make
0:28
sure you stick around to the end to
0:30
hear that. This episode has a ton of
0:32
bonus content. So if you want to hear
0:35
more of our thoughts and API design,
0:37
then head on over to fall
0:39
through.fam slash subscribe and sign up
0:42
today. As always, if you're not
0:44
already, please give us a follow
0:46
on social media and reply to
0:49
the things that we post. And
0:51
if you want to see our
0:53
lovely faces instead of just hearing
0:55
our lovely voices, head on over
0:58
to YouTube and smash our subscribe
1:00
button and don't forget during
1:02
that notification bell so
1:04
you can get notified
1:07
right when our video
1:09
episodes drop. And with
1:11
that, let's get into the show. Today,
1:13
we are talking about API design and all
1:15
of the fun stuff that comes with attempting
1:18
to do design. We have a nice little
1:20
panel today consisting of Ian, one of our
1:22
co-host, and Jamie, one of our guest host
1:24
now. We're just going to call you a
1:27
guest host. That's what you are now. You're
1:29
a guest host. Thanks for the promotion. So
1:31
how are you doing today, Ian? I'm doing
1:33
great. Can't complain. Yeah, it's not raining.
1:35
It's not raining. We've got to stop talking
1:38
about the weather at the weather at
1:40
the weather at the beginning. It's getting boring.
1:42
It's getting boring. It's getting boring. Uh, yeah,
1:44
yeah, we weren't for a while, but
1:46
then I got sad that we were
1:48
talking about the weather, so... I was
1:50
gonna say, do you want to
1:52
talk about current affairs, right? Maybe
1:54
not, maybe not. Let's talk about
1:56
the weather instead of that state
1:59
of the world. fun
2:01
instead of yeah anyway Jamie
2:03
how are you doing today
2:05
I'm doing great thanks it
2:07
is a lovely sunny day
2:09
out here look it's sunny
2:11
in New York it's sunny
2:13
in in the UK it's
2:15
just which is kind of
2:17
amazing isn't usually rainy in
2:19
the UK where the UK
2:21
has a son yeah it's
2:23
very weird last week we're
2:25
away in Wales and we
2:27
expected like a mid-March holiday
2:30
to be awful weather. Like
2:32
several of the days I
2:34
went out with like a
2:36
really light hoodie on. It
2:38
was just unnecessarily unlikely and
2:40
nice. So yeah, it is
2:42
weird that the UK have got
2:44
some this time of year. Yeah, I
2:46
can play. Yeah. Have we gone soon?
2:49
Don't worry. The rain will come back.
2:51
The rain will come back. All right,
2:53
so let's start with talking about API
2:55
design. So we're gonna start the episode
2:58
by talking about our experiences with APIs,
3:00
with designing APIs. So who wants to
3:02
go first? Ian? Ian? Yeah, just add
3:04
to that a little bit. Just like,
3:07
maybe some good things that we've done,
3:09
some decisions we regret, that sort of
3:11
thing, some bad things we've seen. You
3:13
know, just wanna get a survey of
3:16
how we feel about things. Okay, Jamie,
3:18
do you do you have an experience
3:20
that you want to want to start
3:22
with? Yes, I guess I've been building
3:25
APIs for most of my career in
3:27
different languages, different text stacks, those that
3:29
recognise my voice from previous episodes. I'm
3:31
the co-maintainer of our API CoGen, which
3:34
is a go open API to Go
3:36
co-generator, and I've been in the open
3:38
nation community for a while or so
3:40
on. primarily working on web APIs. I
3:43
haven't really done too much with GraphQL
3:45
or JCPC. One of the things I've
3:47
learned is that you will inevitably make
3:49
bad decisions. The annoying thing is I
3:52
can't think of any of the bad
3:54
decisions I've made right now. But I
3:56
know there definitely are some. In terms
3:58
of good decisions, I think one of
4:01
the ones that will touch on a
4:03
little bit later is thinking about versioning
4:05
up front and realizing that this API
4:07
we're building is going to change at
4:10
some point. And one of the projects
4:12
that was technically done where I said
4:14
like we need to think about this,
4:16
and lo and behold, like six weeks
4:19
later, we needed to introduce a breaking
4:21
change. We barely shipped it into production.
4:23
And we were already like, oh. We
4:25
made a massive mistake. We need to
4:28
change something. And because we have thought
4:30
about that, we were able to really
4:32
straightforwardly fix it in a way that
4:34
our consumers did also needed very little
4:37
work. And it just made everyone's life
4:39
nice and easy. Yeah. Yeah, I guess
4:41
that's one of the one of the
4:43
struggles with the industry the way it
4:46
is now is that very often we're
4:48
not around to see the repercussions of
4:50
some of the design decisions we make.
4:52
So you can usually see some of
4:55
the good ones, but it's more difficult
4:57
to see the negative consequences of APIs
4:59
you've designed. I think that for me,
5:02
I will say that like my experience
5:04
in designing APIs, when I when I
5:06
when I take more time to think
5:08
about an API design, I have found
5:11
generally that I don't regret that in
5:13
the future. Right. Like I don't regret
5:15
spending more time thinking about like how
5:17
do I. What are the objects that
5:20
I'm trying to work with? How should
5:22
I think about them? What are the
5:24
actions you might be wanting to take
5:26
on them? When I spend more time
5:29
on that, it feels like things fit
5:31
together. When I don't spend enough time
5:33
on it though, that does... feel like
5:35
it's led to more like, oh, now
5:38
we have to like shoehorn in this
5:40
awkward concept, this awkward new concept that's
5:42
harder for people to understand, and now
5:44
it's like the API doesn't feel like
5:47
a cohesive hole. I think from an
5:49
aesthetic perspective, spending more time on an
5:51
API has been more valuable than trying
5:53
to spend less time and just get
5:56
something out the door, which I think
5:58
is what we're going to talk about
6:00
later in the episode as well. But
6:02
I think that's that's an important aspect
6:05
of it. to like an MVP for
6:07
an API, they want to be like,
6:09
we got to get this thing out
6:11
there, we got to ship it and
6:14
get into people's hands. And I think
6:16
there's space to do that, but I
6:18
also think that if you don't, if
6:20
you don't want to have to rebuild
6:23
or don't have a process that allows
6:25
you to rebuild by literally being able
6:27
to rebuild or don't have a process
6:29
that allows you to rebuild by literally
6:32
being done thinking about your thinking about
6:34
the door, at least that's been my
6:36
experience. Yeah, I'll pay you back on
6:38
that, but I do have experience putting
6:41
out kind of these MVP style APIs.
6:43
There's one I'm thinking of that is
6:45
for, let's just say reporting on a
6:47
large amount of data, and our MVP
6:50
version didn't have page donation. And, you
6:52
know, it started to cause issues where
6:54
like a page in Chrome would not
6:56
load because it returned too much data.
6:59
and you go to shoehorn and page
7:01
a nation and all of a sudden
7:03
you realize you're cashing strategies, you're like
7:05
the stack all the way down. Like
7:08
kind of needed to account for that,
7:10
right? So I would agree that like
7:12
kind of upfront thought does make a
7:14
huge difference. Yeah. I think too, like
7:17
one of the one of the other
7:19
experiences I've had is having to. Basically
7:21
invent everything from whole cloth every time
7:23
you go to design an API, which
7:26
I found frustrating of like, you know,
7:28
if you want to do pagination, like,
7:30
how do you actually approach that? Because
7:32
there's many, many different ways of doing
7:35
it. But then also there's like this
7:37
huge tale of like other considerations. I
7:39
think the initial. thing of like let's
7:41
do pajination is like easy to think
7:44
about because you're like okay I will
7:46
just stick like a next previous on
7:48
my response I get back but then
7:50
you're like okay but how does that
7:53
actually work right okay now you get
7:55
into your application layer and you're like
7:57
okay well I guess now I have
7:59
to have a way of querying the
8:02
data in such a way that I
8:04
can bound it around this. You're like,
8:06
OK, well, maybe the database can do
8:08
that for me. But it's like, OK,
8:11
well, are you going to hold a
8:13
transaction open? OK, well, you know, you're
8:15
not going to hold a transaction open,
8:17
because most databases aren't built to do
8:20
that. OK, well, if you're not going
8:22
to hold the transaction open, because most
8:24
databases aren't built to do that. And
8:26
I think also like at that point
8:29
you're then potentially tying like your transfer
8:31
layer all the way to your storage
8:33
layer like you now need to tie
8:35
that knowledge of okay my web app
8:38
is doing pagination in this specific way
8:40
with say a cursor. Oh actually how
8:42
do I get that cursor out the
8:44
database? What if for some reason we
8:47
end up changing the database? Like how's
8:49
that going to work? Right. And then
8:51
if you do want to do something
8:53
where you have you know I guess
8:56
it's also part of like the API
8:58
design part of do you return stable
9:00
results between pages? Because you could say
9:02
no, and then this isn't a problem
9:05
at all. But if you say yes,
9:07
that's going to constrain not just how
9:09
your application layer works, but also how
9:11
your storage layer works, because you need
9:14
a storage layer that is capable of
9:16
basically doing snapshoting, and then there's a
9:18
whole bunch of other stuff that goes
9:20
around snapshots and also questions of like,
9:23
how long do you keep? these snapshots
9:25
around? Like, how long is it valid
9:27
for someone to hit that next or
9:29
previous button and get the same results?
9:32
But in the expectation. So even something
9:34
as simple as pajination found is like,
9:36
no, this actually leads to, as we
9:39
just said, a plethora of very challenging
9:41
questions that go deep, deep, deep into
9:43
the design of your system for something
9:45
that seems like it should be pretty
9:48
simple. And I, I wish that we
9:50
as an industry had more of like
9:52
a development kit for this sort of
9:54
thing or more of like a design
9:57
development kit where you're just like here's
9:59
a standard way to do this patchination
10:01
for this type of stack. But I
10:03
think that like that doesn't, you can
10:06
find stuff out there of people saying
10:08
this is how you can implement patchination,
10:10
but I don't think there's that kind
10:12
of comprehensive thing out there that can really,
10:14
I guess, talk about what we just talked
10:17
about of like, yeah, no, this just gets
10:19
spread all over your, all over your code.
10:21
And you have to decide from the beginning
10:23
what you're going to do about it. And
10:25
like, there's other ways to deal with this.
10:27
in your data model, you can structure data
10:29
and you can put constraints on your data
10:31
so that you'll never return so much data
10:33
that it would become something you would need
10:35
to passionate. So that's another way to deal
10:37
of saying we're not going to patch and
10:39
eight, but we're going to change our data
10:42
model so that doesn't happen. That's like what
10:44
I ended up doing is we went down the
10:46
route of page donation and we're like, all right,
10:48
our requirements where we need to return
10:50
stable data, like, and at the end of the
10:52
day, we just put a limit on like, like, like,
10:54
like, like, like, like, query cardinality and
10:56
said like, all right, well, if
10:58
you want to query all this
11:01
data, just query these four instead,
11:03
right? Right. Yeah, I think like, yeah,
11:05
which is not the best experience and
11:07
I would have liked to just pageinate
11:10
from the beginning, but right.
11:12
So I think that's definitely
11:14
one of my experience has
11:16
been like, we, we wind up having
11:19
to read, but you have to wind
11:21
up redefining all of these things like
11:23
deep down into your API. time, especially
11:25
the APS as a consumer I found
11:27
is that people didn't think about that
11:30
as much from the beginning. And that's
11:32
I think what also leads to people
11:34
in who do breaking changes because they're
11:36
like, oh, we didn't think about this.
11:39
And now we have to figure out what
11:41
we're going to do because our servers are
11:43
following over. I think as well in terms
11:45
of like creating it from scratch, as
11:47
you say, it's sometimes also feeds into
11:49
if you're working in an organization with
11:52
at least one other team. Or maybe
11:54
your team has already done it. So
11:56
sometimes you can leverage like other things
11:58
that people have done. like the scale
12:00
of the organization you may have pre-built
12:03
like service templates that actually do a
12:05
lot of that hard work for you and provides
12:07
it in a consistent way in both
12:09
like a service code wise as well
12:11
as a actual API contract that can
12:13
be really convenient and like I worked
12:16
in some organizations where it's been really
12:18
straightforward to just get up and go
12:20
because the work has been done that
12:22
upfront thinking someone's done a while back and now
12:24
you can just take advantage of it and
12:26
don't think as much. But then the problem
12:28
is okay but What if I don't like
12:31
it? Well I think the other problem
12:33
there is I guess what comes with
12:35
experience is like you kind of
12:37
think there's a right way to do
12:39
things for an API design and you
12:42
think like oh this is how you
12:44
know maybe this is how stripe does
12:46
it or this is how Facebook does
12:48
it so that's the right for me
12:50
and I think from experience like you
12:52
start learning that there isn't a right
12:54
like good way to do things and
12:56
it really like everything in software. It
12:59
depends so heavily on your use case.
13:01
I mean just that page donation one
13:03
like if like yeah if you don't
13:05
need consistent results if you don't need
13:07
all of that like yeah the one-size-fits-all
13:09
just like just works but in a
13:11
lot of cases it just won't. Yeah I
13:13
mean I think a good example also of
13:15
like where your data might just lend
13:18
itself to good patchination if you
13:20
just change the criteria that you're pageinating
13:22
on is like how get hub does
13:24
pajination on a branch, right? So like
13:26
a branch, you do have a stable
13:28
and consistent order for things. I mean,
13:30
assuming you don't force push that branch,
13:33
but that's a whole other concern. But
13:35
you can just be like, oh, like,
13:37
before or after, like, before a certain
13:39
commit, give me this many commits, right?
13:41
And you can do pajination based off
13:43
of that instead of doing a page
13:46
one, page two, page two, page two,
13:48
page two, page three, page three, the
13:50
concept of patchination to the data
13:52
that you're actually patching through. So I
13:54
think sometimes if people hear something like,
13:56
patchination, they think like, oh, I have
13:59
like page one, page two. page three and all
14:01
of that, but like you don't necessarily
14:03
have to have it work like that.
14:05
You also don't necessarily have to have
14:08
it work in both directions, right? You
14:10
can have only pagination forward and have
14:12
no way to go back except for,
14:14
you know, your your browser's back button,
14:17
perhaps. So I think that really part
14:19
of it and part of my experience
14:21
in like how I thought about APIs
14:23
to challenge your initial assumptions. about what
14:26
you're building. So I think I found
14:28
that when I try to design an
14:30
API and it's not working, it's usually
14:32
because one of my underlying assumptions is
14:35
incorrect. It's like, or just isn't, I
14:37
guess incorrect, maybe not the right word,
14:39
but it doesn't fit the type of
14:41
thing that I'm trying to do. Also,
14:44
I think that you were right on
14:46
the idea like, I don't think. there
14:48
is a correct way to design an
14:50
API. I think correctness is the wrong
14:53
way to frame any of this. In
14:55
the same way that like it's incorrect
14:57
to frame like language as being correct
14:59
or not, I guess aside from maybe
15:02
French because French does have some standardization
15:04
to it, but like English, there's no
15:06
such thing as like correct English, right?
15:08
So I think there's no such thing
15:11
as like a correct API. It's like
15:13
was the person who you meant to
15:15
use the API able to do what
15:17
they wanted to do. And I think
15:20
if you start with that as an
15:22
idea, I think that leads to better
15:24
API designs than if you attempted to,
15:27
you know, go for some sort of
15:29
correctness or go for some sort of,
15:31
and we'll get into this a little
15:33
bit later, but some sort of like
15:36
technically correct ideology. Also sometimes you don't
15:38
need to sit down and think about
15:40
something all the way through and sometimes
15:42
it is good to just throw something
15:45
out there if it's a well-skip problem
15:47
that just... that you can really just
15:49
write something around and throw out there
15:51
and it works for people and it
15:54
solves their problems. So I think that
15:56
can happen with APIs too, if it's
15:58
a small one of things. So I
16:00
think also as part of my experience,
16:03
it's like if you build something, it
16:05
depends on the size of the thing
16:07
that you're building, whether you need to
16:09
put a ton of thought. into it
16:12
or not. You're building a tiny little
16:14
thing. You can probably get away with
16:16
not having to put as much line
16:18
to it as, you know, you might
16:21
otherwise want to do. I've kind of
16:23
had the opposite end of that, where
16:25
at a previous trial, I was building
16:27
like some workforce management, like kind of
16:30
automation tools. And, you know, so we
16:32
sit down with that team and we
16:34
really understand how everything works. And we
16:36
get these flows down really well, you
16:39
know, like when this happens, you know,
16:41
it kicks off all of this. And
16:43
it's going well for like three days.
16:45
And then someone says like, oh, but
16:48
you know, I had a chat with
16:50
the guy and we don't want to
16:52
do this anymore. And so like almost
16:54
over constraining can also be bad, like
16:57
if that makes sense. When you're modeling
16:59
things, like I think it's kind of
17:01
important to have kind of like an
17:04
out button, you know, like a all
17:06
right butt. Let's just do this this
17:08
thing because does it make sense like
17:10
flexibility? Yeah, I feel like that I
17:13
really will talk about the more we
17:15
get to the whole technically correct part
17:17
of the conversation. Yeah, I guess this
17:19
was a technically correct API, but at
17:22
the end of the day, it doesn't
17:24
meet their needs because they don't do
17:26
everything technically correctly every time. Right. There's
17:28
so many, so many words I want
17:31
to like get into about like how
17:33
we. Because I think it is important
17:35
to under, like it frames the way
17:37
that we perceive the things that we're
17:40
creating in this like, oh, well, like
17:42
technically correct. It's like, is it correct
17:44
if it's not useful? I think that's
17:46
like a good, like a good question.
17:49
Like when we say technically correct, what
17:51
are we actually calling correct and all
17:53
of that? Who's some meta? Okay, we
17:55
can get into that. But first, before
17:58
we get into that, I think the
18:00
first thing we should talk about. Even
18:02
though we've talked about a whole bunch
18:04
of stuff, but I think that's stuff
18:07
we've talked about so far really goes
18:09
into this idea of having a theory.
18:11
for your API. Right. So having a,
18:13
oh God, Siri thought I said Siri.
18:16
Anyway, having a theory for your API.
18:18
And there's a lot that goes into
18:20
that. I think that part of it
18:22
is about having an ethos of what
18:25
your API is. So like a, I
18:27
guess you could say a vision or
18:29
what is it we want our API
18:31
to be capable of doing? There's also
18:34
the parts of documenting that theory so
18:36
you can actually refer to it again
18:38
later and a whole bunch of other
18:41
stuff. But I would say we should
18:43
start with this idea of like an
18:45
ethos of your API, which for me
18:47
I would define that as what is
18:50
the world or the universe of things
18:52
that you want your API to be
18:54
capable of doing? And I think that
18:56
thinking, yeah, I think about that and
18:59
like the abstract, which I think is
19:01
really hard. So I think we should
19:03
talk about that, because I think this
19:05
is going to be confusing for a
19:08
lot of people. So I think a
19:10
lot of people are used to having
19:12
a concrete problem that they are trying
19:14
to solve with the API they're creating.
19:17
So you have an application, your application
19:19
does things X, Y, and Z. And
19:21
I think when you enter into designing
19:23
an API like that, you immediately back
19:26
yourself into several corners. Because now if
19:28
your API also needs to do thing
19:30
A and B and B and C.
19:32
but you designed it only to do
19:35
X, Y, and Z, you have to
19:37
like basically shoehorn all of that stuff
19:39
into the old one or build a
19:41
whole new API and figure out how
19:44
to make those compatible or you're just
19:46
making it so down the road you're
19:48
going to have more problems. But if
19:50
you have a more ethos, more generalized
19:53
approach or at least a generalized understanding,
19:55
it can be easier to integrate those
19:57
things. So what do you two think
19:59
about that concept? I guess, do you
20:02
agree with that concept? And then do
20:04
you, what are your thoughts about how
20:06
you've gone about having an ethos for
20:09
your API or an API? I think
20:11
I kind of share. what you're saying,
20:13
maybe not in as grandiose terms as
20:15
an ethos, but what I'm hearing is
20:18
this idea of kind of shared details
20:20
throughout the API, right? Like this idea
20:22
of an ethos, maybe not even around
20:24
functionality, but like around building expectations. Like
20:27
I think if you return errors, you
20:29
should return errors the same way each
20:31
time. I think if you return. an
20:33
air code here, you should also return
20:36
an air code here if you return
20:38
certain metadata one place about the request.
20:40
It should probably just be everywhere, right?
20:42
I also, I think part of that
20:45
ethos is also like making decisions on
20:47
how you're dealing, are we doing like
20:49
a domain model type thing, like a,
20:51
like resources, or are we doing like
20:54
more, I don't know what to call
20:56
it. like page by page APIs, like
20:58
that kind of stuff. I'm not recommending
21:00
that, but like just having an idea
21:03
of how you're building things and keeping
21:05
that consistency. I feel like maybe a
21:07
word, a less grandiose word than ethos
21:09
would be foundation. So your API should
21:12
have a foundation to it of like
21:14
here's the basics, the mechanics of how
21:16
it works. If that's what that's what
21:18
I got from what you said. So
21:21
yeah. And I really do think building
21:23
that is about the details. It's about
21:25
the details. Yeah. Jamie? Yeah, I think
21:27
I'd potentially see that more as like
21:30
a style guide, maybe, and thinking more,
21:32
well, a mix of a style guide
21:34
and more generally, like, what do we
21:36
actually want the APA to be doing?
21:39
What is its purpose in the world?
21:41
Like, what do people want out of
21:43
it? Because, yeah, like, you could just
21:46
go away and build it. And as
21:48
you say, paint yourself into a yourself
21:50
into a corner. But taking a step
21:52
back and thinking, okay, so one of
21:55
the APIs built in the past was
21:57
called the Care Request API and it
21:59
was for So the idea is, someone's
22:01
got a complaint, so they get in
22:04
touch, they get a care request ID
22:06
created for them, and then everything is
22:08
based off that original parent request ID.
22:10
So we took us out back and
22:13
we were like, okay, are we sure
22:15
this is the right way of interacting
22:17
with this? Are we always going to
22:19
have one of these things in place?
22:22
And if so, does it make sense
22:24
for us to, cool, that's actually the
22:26
care request API? or should it be
22:28
something different and in this case it
22:31
made sense we had done some thinking
22:33
both like a product design and engineering
22:35
point of view to actually work out
22:37
like does this fit in the grand
22:40
scheme of where we're going is like
22:42
a platform that's the other thing is
22:44
yeah maybe more grandiose and thinking okay
22:46
where does this fit into the rest
22:49
of the organization where does this fit
22:51
into the other stuff we're doing? Because
22:53
sometimes, like you'll go and build a
22:55
thing, and it turns out three teams
22:58
have already built it, and you could
23:00
have just used one of those. This
23:02
is something, so I had a brief
23:04
stint in the UK government, and one
23:07
of the stats that I learned from
23:09
it, I bringing up every chance I
23:11
get. So the UK's Department for Work
23:13
and Pensions at the time, had a
23:16
number of different APIs, which would basically
23:18
look up. a postcode or an address
23:20
and give you more information about it.
23:23
They had 27 different versions of the
23:25
same API and in some cases it
23:27
was an end point some cases it
23:29
was a full API and it's like
23:32
come on if you just chatted to
23:34
each other maybe you would have found
23:36
that someone's already built it multiple teams
23:38
have already built it and so I
23:41
think yeah thanks to step back thinking
23:43
about what you're trying to build Where
23:45
does it fit? Is it like a
23:47
short term thing that you're thinking? We
23:50
just need a little... for the short
23:52
term and in the future will be
23:54
replaced by this other thing or thinking
23:56
that and then being wrong is also
23:59
fine because a lot of oh this
24:01
is only like a this is a
24:03
hack it's fine that then just lasts
24:05
for years and years and becomes very
24:08
load bearing yeah I think I'm just
24:10
thinking more about like this ethos and
24:12
kind of what you said Jamie but
24:14
I think a good example here is
24:17
we have an API for, you know,
24:19
our, the single tenant and, you know,
24:21
different customers can call into a get,
24:23
to get data out. And kind of
24:26
the initial build of that, you know,
24:28
you had to send like a customer
24:30
ID which each request to say, like,
24:32
I am this customer. And at one
24:35
point we were thinking, like, well, that
24:37
doesn't make sense. Like, we have their
24:39
token. These APIs should not be based
24:41
around. this customer it should just be
24:44
like give me the data and I
24:46
know what customer right and that's kind
24:48
of a mistake we built we built
24:50
in and are still dealing with right
24:53
and if we would have at the
24:55
beginning been like this is what this
24:57
API is for like we have routes
25:00
that like you have to put the
25:02
customer name in the route to get
25:04
data back and so then you have
25:06
to like in your docs be like
25:09
here this is your customer key and
25:11
you have to put this in your
25:13
API endpoint right So like knowing up
25:15
front that like this is an API
25:18
for our customers to get data would
25:20
have made that so much nicer so
25:22
that that's like kind of it's not
25:24
a style guide it's not anything like
25:27
that but that's part of that ethos
25:29
right like this is what this API
25:31
is for and we can design it
25:33
in these ways I think I think
25:36
part of what both you said though
25:38
I think it is in the not
25:40
in the way we as an industry
25:42
user term style guide but in the
25:45
way that the industry that originally the
25:47
term style guide uses style guide so
25:49
the publishing industry in that style guides
25:51
are really about guidance to help you
25:54
make decisions and knowing if the decision
25:56
you've made fits with the rest of
25:58
whatever the unit is that you're working
26:00
with right so like if you you
26:03
know if you look back at how
26:05
like you know how style guns are
26:07
used in publishing right in a kind
26:09
of broad sense you have you know
26:12
usually a publisher will have a style
26:14
guide so you know you have like
26:16
Chicago University Press right they have a
26:18
style guy called the Chicago Manual style
26:21
that lots of other people use. And
26:23
then, or like the New York Times
26:25
has their own style guide, and the
26:27
AP has a style guide, so everybody
26:30
has style guides. But then for, if
26:32
you're publishing books, you often have a
26:34
style guide for that book specifically that
26:37
derives from the larger style guide and
26:39
can like make overrides. This is also
26:41
where like, you know, we kind of
26:43
get the idea of cascading style sheets
26:46
like they were called style sheets at
26:48
one point, because they were a sheet
26:50
until they became something larger. But like
26:52
the way that a style guide functions
26:55
is that it's this thing to help
26:57
you, to help guide you, to help
26:59
you understand how you can build something
27:01
in this case, in the case of
27:04
publishing, writing, that actually aligns with the
27:06
rest of the writing system. So that's
27:08
why New York Times articles are New
27:10
York Times articles. This will make them
27:13
feel like New York Times articles is
27:15
that they follow a specific style guide
27:17
that's not about necessarily, you know. This
27:19
is where you put punctuation and this
27:22
is the punctuation you use, but also
27:24
like this is how you structure an
27:26
article. This is how you, you know,
27:28
if you have to deal with, this
27:31
is how you refer to specific things,
27:33
is how you cite things. And I
27:35
think that's something that is usually missing
27:37
from the APIs that we designed, is
27:40
this idea, and that's how you wind
27:42
up with like, you know, seven different
27:44
ways of doing things. Like we were
27:46
talking about pagination. And with pagination, there
27:49
are. lots of different ways to doing
27:51
it. So I think when you start
27:53
developing your ethos or your theory of
27:55
your API, that's a decision you can
27:58
make more or less up front and
28:00
you can say, all right, we're going
28:02
to do pagination in this way. That
28:04
doesn't mean that. every single API, endpoint
28:07
or API thing that you create has
28:09
to follow that. That's not what it's
28:11
about. It's saying if, like, if there's
28:14
not a reason to not follow this,
28:16
do it in this way. But if
28:18
you have a reason that like, oh,
28:20
well, this data model doesn't work for
28:23
the pagination design that we chose. Okay,
28:25
then use a different pagination style. The
28:27
thing that a theory or an ethos
28:29
gives you is not only a way
28:32
to know what you should do by
28:34
default, but it also gives you a
28:36
way to ensure that when you deviate
28:38
from that default, you are justified or
28:41
there's justification that you can write down
28:43
or you can document so that when
28:45
your users or consumers are using your
28:47
API and something looks a little weird,
28:50
you can just point out like, oh,
28:52
this API doesn't use the standard patchination
28:54
because X, X, Y, So you can
28:56
surface that to their users. So when
28:59
the person's consuming it, they don't get
29:01
all confused about like, oh, but I've
29:03
been using this patronage in style, why
29:05
doesn't it work for this one? And
29:08
there's no documentation that may just be
29:10
confused or lost and not be able
29:12
to figure out what went wrong. And
29:14
that's just a. worse experience for them.
29:17
So if you have this documentation, if
29:19
you have this style guide or this
29:21
theory or this ethos or whatever you
29:23
want to call it, and you're using
29:26
that to build things, you understand where
29:28
you need to document things, where you
29:30
need to surface things, and it helps
29:32
you design more robust things in the
29:35
long term, or recognize when what you've
29:37
built no longer serves the purpose that
29:39
you had for it, right? So if
29:41
you say... Oh, I want to build
29:44
this new type of API, or have
29:46
this application that needs this new type
29:48
of data. And you're like, well, this
29:51
isn't fitting with this theory. Perhaps that
29:53
means you need to build a completely
29:55
new thing instead of adding to the
29:57
thing that you already have. So in
30:00
publishing, and I think for us as
30:02
well, we should see style guides or
30:04
what we're kind of referring to as
30:06
a theory or an ethos or foundation
30:09
as a decision making system, Because I
30:11
think when people hear the word style,
30:13
they think of... more or less superficial
30:15
things that are annoying but not core
30:18
to what you're doing, which is very
30:20
much not what the ethos of a
30:22
style guide is. Yeah, just to quickly
30:24
jump in there, so I think I
30:27
put us on a bit of a
30:29
tangent by saying style guide. I think
30:31
that was in particular, like, talk about
30:33
these are the way errors should be
30:36
returned and stuff like that, which I
30:38
do see as separate to kind of
30:40
the foundation point of view. which is
30:42
like what is this API actually for?
30:45
And trying to provide like, do these
30:47
things actually fit within here or should
30:49
they go somewhere else? Yeah. Right. I
30:51
think it's all I think it's all
30:54
related together. I think that's like the
30:56
challenge there. I would say too. I
30:58
think these things shouldn't be separated. I
31:00
think we tend to want to separate
31:03
like a style guide from like a
31:05
design system maybe. We don't have a
31:07
lot of good terminology terminology for this
31:09
around API. I think that's part of
31:12
the problem. But I think like, yeah,
31:14
these things are all really like, how
31:16
do you return errors? Or when do
31:18
you return errors? Or should you return
31:21
errors? I think all of that rolls
31:23
into, like it has larger implications for
31:25
AP as a whole. Let's say with
31:28
that, like, you know, pagination, which we
31:30
were talking about, like, how like, pagination,
31:32
can sprawl itself across your entire code
31:34
base. So it's, you know, I think
31:37
some people might just stick that in
31:39
a style in a style of kind
31:41
of kind of kind of like, like,
31:43
just giant ripple and repercussion effects across
31:46
everything you're doing. So if I was
31:48
making a new API, like how would
31:50
you sit down and build this foundation?
31:52
Like any tips? I mean, I know
31:55
how I would do it, but I
31:57
don't know if my method would work
31:59
well for other people, because I would
32:01
just sit down and start writing. But
32:04
there's other ways you can do that.
32:06
You can do that through diagramming. You
32:08
can do that through other forms of
32:10
drawing pictures. You can do that by
32:13
just talking with other people, right? There's
32:15
lots of ways you can do that.
32:17
But I think that's where I would
32:19
start is with, let me kind of,
32:22
I guess, brainstorm might be the right
32:24
word there of letting yourself. explore more
32:26
or less without constraint until it feels
32:28
like you've maybe wandered off a little
32:31
too far and you need to come
32:33
back. But in general I think wandering
32:35
exploration thinking of the different ways that
32:37
this thing you're building might be used
32:40
is a good place to start. And
32:42
then at some point you do need
32:44
to write it down. You need to
32:46
document it in some way because you
32:49
don't document you're going to forget about
32:51
all of that thinking you just did
32:53
and it's not going to be very
32:55
useful in the long run. for whoever
32:58
is going to consume the API, right?
33:00
Because it's like a good way to,
33:02
I don't know, kind of distill all
33:05
the pertinent information into one place and
33:07
it ends up kind of being like
33:09
that, that not style guide, but like
33:11
foundation guide, right? Because it has all
33:14
the shared things, the shared three lines,
33:16
it has kind of the ideas and
33:18
how to think about things. That's worked
33:20
really well for me in the past.
33:23
Yeah, I was going to say I'm
33:25
probably a mix of the two. It's
33:27
more when there's like more of a
33:29
rigid or like reasonably good design documentation
33:32
process, design doc. We're going through that,
33:34
like it prompts out a few questions,
33:36
like what's the purpose of the thing
33:38
you're trying to build? And what would
33:41
be the main consumers? How does it
33:43
fit into like long-term strategy? Blah blah
33:45
blah blah. But then as you say,
33:47
Ian, like also going through the Quick
33:50
Start guide and I find like a
33:52
huge amount of value. writing documentation driven
33:54
development. So thinking, okay, what are the
33:56
docs that I would want to write
33:59
for someone who is coming to this
34:01
API for the first time? And what
34:03
are the key things they're going to
34:05
need? Like, it's quick start. But also,
34:08
like, as you start, like, writing things
34:10
out and saying stuff like, oh, and
34:12
to do this, you need a API
34:14
key from this system. And it's like,
34:17
oh, actually, should it be from that
34:19
system? Like, how would they go and
34:21
get that? Yeah, I think again, thinking
34:23
through writing, but also trying to go.
34:26
a little bit with the empathy of
34:28
the user and trying to work out
34:30
like what they want out of it,
34:32
as well as also from my point
34:35
of view as the designer of the
34:37
API, what am I trying to solve
34:39
more generally as well. Yeah, what else
34:42
do you think goes into a theory
34:44
of an API? Some of the things
34:46
we have listed here, documenting things, so
34:48
I think maybe we can talk a
34:51
little bit about how you actually document
34:53
some of this stuff. We also have,
34:55
you know, prior art. Which I think
34:57
is a good thing to talk about,
35:00
and we often, you know, it gets
35:02
framed as don't reinvent the wheel, but
35:04
I think talking about it as prior
35:06
art and talking about how do you
35:09
go find that prior art, I think
35:11
is an important thing. And we also
35:13
have that fun, technically correct, versus human
35:15
usable. So which of those three things
35:18
we want to talk about first? I
35:20
mean, just on the prior art front.
35:22
Okay, prior art. I do think, like,
35:24
like, throughout my career, I've written so
35:27
many integrations. with other people's APIs. And
35:29
I do think it's hard to kind
35:31
of build a good API without interacting
35:33
with a lot of them. Like you
35:36
really do just gain experience from, I
35:38
don't know, mostly bad things. Like, I
35:40
mean, like this is a pain. I
35:42
don't like doing this, right? Yeah, I
35:45
don't know. It's like, I don't know.
35:47
They tell writers to read a lot.
35:49
Like, so if you get the chance
35:51
to to integrate with other APIs, like,
35:54
do it because you will learn with
35:56
it. and it kind of goes back
35:58
to conversation earlier around like being around
36:00
long enough to see the failures. But
36:03
say for instance like you integrate with
36:05
someone's API and then they break things
36:07
or they change things. How do you
36:09
respond to that? How deeply integrated in
36:12
your own code basis are they? Because
36:14
there are ways that you can build
36:16
things that provide like an adapter layer
36:19
or something that makes it a lot
36:21
bit easier for that separation, but that
36:23
adds complexity and the more layers you
36:25
add the harder things are. and depending
36:28
on if you've done that right, that
36:30
can be quite painful. I think as
36:32
well with prior art it's, again, like
36:34
if you're in a larger organization where
36:37
maybe you've already tried to build this
36:39
API, maybe there's a slew of previous
36:41
attempts, why have they all failed? And
36:43
what are you going to do that's
36:46
actually going to get it right? Because
36:48
chances are you're not going to get
36:50
it right? Because if there's already this
36:52
prior knowledge, there's probably a reason that
36:55
we're not quite going around it the
36:57
right way. And even like outside of
36:59
your organization. There are lots of people
37:01
building different things. So yeah, how can
37:04
you learn from them? So I also
37:06
think in addition to like reading prior
37:08
art that's into your company or external
37:10
company, I think sometimes looking at like
37:13
what's already been specified is also helpful.
37:15
Like I've started finding a lot of,
37:17
especially IETF, the Internet Engineering Task Force
37:19
specifications for things that I didn't really
37:22
think that they would be specifying. Some
37:24
of them are older than. I thought
37:26
to, for instance, I was thinking about
37:28
authentication using one-time passwords, because I'm actively
37:31
building out like an off system. And
37:33
I realize that like, oh, both the
37:35
H-Mac-based one-time passwords and the time-based one-time
37:37
passwords were H-O-T-P-T-O-T-P are things that have
37:40
I-E-T-F-R-F-C-F-R-F-C-I-E-T-F-T-F-F-T. which is helpful because when you
37:42
just kind of Google around on the
37:44
internet for this, there's a lot of
37:47
information and content that explains what the
37:49
thing is and in very broad strokes,
37:51
explains how it works, but does not
37:53
actually tell you how it works. It
37:56
doesn't give you the specification of if
37:58
you want to implement T-O-T-P, this is
38:00
how you go through and do it.
38:02
Instead, it's just like, this is how
38:05
T-O-T-T-P works and go use... Usually because
38:07
it's on some blog for some offices
38:09
service like go use our service to
38:11
do all of your TOTP needs. And
38:14
in fact, use us for all of
38:16
your authentication needs. And I think it's
38:18
easier when you can just sit down
38:20
and read the thing and understand what
38:23
it's saying. And then also, it gives
38:25
you space to maybe adapt that thing
38:27
if you need to adapt it, or
38:29
at least be able to implement a
38:32
compliant version of that thing that will
38:34
work with all of the other things,
38:36
which is nice. Reading RFCs is a
38:38
little bit of a skill because they
38:41
are fairly technical because they are technical
38:43
specifications. They're things that generally try to
38:45
have very little room for like subtlety
38:47
on your wants like they're trying to
38:50
be very clear on this is how
38:52
you implement the thing in one of
38:54
my past jobs we were looking at
38:56
implementing an RFC for HSP signatures. as
38:59
a means for like security and integrity,
39:01
which is instantly also implemented in Macedon.
39:03
And I know a number of people
39:05
who've had to fight reading the RFCs
39:08
and work out like what that is,
39:10
all this stuff. And I remember going
39:12
through it and being like, yeah, it
39:14
is interesting, it is difficult and it
39:17
is also interesting because like you yourself
39:19
could just go and write on in...
39:21
similar level of depth and stuff, but
39:24
it takes time, it takes a lot
39:26
of different people, different viewpoints, and some
39:28
of the conversations and the different revisions
39:30
that get there before it actually gets
39:33
published, also does share some interesting things
39:35
about the different things people are doing
39:37
with standards and how they develop. One
39:39
other like ancillary benefit is it kind
39:42
of teaches you how to think, like,
39:44
when you're designing an API, like, it's
39:46
kind of easy to get like the
39:48
broad strokes in your head, right? But
39:51
I think consuming more documentation and specifically
39:53
RSCs like kind of teaches you how
39:55
to refine. that definition, right? Yeah, I
39:57
would recommend. You always have to read
40:00
them at least twice though. Yeah. I
40:02
also think it can help, and I
40:04
think prior art in general can help
40:06
with you properly framing the different ways
40:09
that you're going to build a future
40:11
like we talked about before, the idea
40:13
that you want to. you know, have
40:15
this foundation or have this ethos that
40:18
you are basing everything off of and
40:20
there's all these little parts of that
40:22
ethos. And I think it's helpful if
40:24
you kind of compartmentalize those parts of
40:27
the ethos into their own thing, that
40:29
part of the theory into its own
40:31
thing, that can then be referenced later,
40:33
which is what a lot of these
40:36
specifications do, like the HTML specification isn't
40:38
just one specification, there's also a specification
40:40
called the infrastructure specification that says this
40:42
is the infrastructure for all of our
40:45
specs, so this is how all of
40:47
our specs works. There's also one for
40:49
the DOM, there's also one for, there's
40:51
basically a whole bunch of different specifications
40:54
that all kind of come together to
40:56
form what is HTML. And CSS works
40:58
in the same way, but to an
41:01
extreme degree, because they have the idea
41:03
of a CSS module and then levels
41:05
for that module, which is a super
41:07
interesting way to do versioning. But it's,
41:10
you know, everything is broken into pieces,
41:12
and those pieces fit together into the
41:14
cohesive whole. And I think that's a
41:16
good way to design any larger app,
41:19
larger API. So I also think that
41:21
we tend to think about APIs needing
41:23
to be a monolithic thing, but I
41:25
don't think we actually need to think
41:28
about them in that way. And that
41:30
gives you the ability to have flexibility
41:32
to have flexibility. The
41:37
way we've been talking, like it seems
41:39
like you should sit down and do
41:41
like a multi-week design of your whole
41:44
API before you start coding it. And
41:46
I want to specify that, at least
41:48
I don't think that is what we're
41:51
advocating for. Like, no. I know, um,
41:53
I think it's the opposite, Chris, before
41:55
the call was talking about how he
41:57
loves doing vibe coding. Just like excuse
42:00
me Sir Like the design process of
42:02
the API Sorry, I'm just gonna skip
42:04
over the vibe coding because The the
42:07
idea that you could sit down and
42:09
design everything before you touched any code
42:11
is kind of that's not a good
42:13
idea I wrote a whole article about
42:16
that. I guess what I'm getting at
42:18
is like, there is, the two are
42:20
intermingled, right? Like you need to do
42:23
these exploratory phases of coding before you
42:25
can actually understand what it is that
42:27
you're designing? Does that make sense? I
42:29
think the idea that you can design
42:32
something without ever writing code is a
42:34
falsity. Yes. Wherever, however people came up
42:36
with that, which I think comes from
42:39
the big up front design idea. And
42:41
really, I think that comes from the
42:43
mistaken belief that you can do this
42:45
kind of construction analogy from people that
42:48
understand construction where you can write some
42:50
blueprints and then you have people that
42:52
build the thing and then that's how
42:55
things work. That's not at all how
42:57
things work. that has bled into us
42:59
or led us to believe that you
43:01
have the separation of a design is
43:04
like a written document and you write
43:06
it and you and it's possible to
43:08
write it without writing any code but
43:11
I don't think you can actually write
43:13
a correct design if you haven't actually
43:15
written code. That's not how, certainly not
43:17
how specifications ever work and I don't
43:20
think that's how anybody that wants to
43:22
realistically implement an API would work. I
43:24
think a good example of this is
43:27
how Web standards are developed. So if
43:29
you want to add a feature to
43:31
each TML or CSS and have that
43:33
be in browsers, it's not like they
43:36
sit down and they think and they're
43:38
like, this is how we think it
43:40
should work. And they designed that, and
43:43
then they're like, here you go, worlds.
43:45
What they actually do is they sit
43:47
down, and they come up with basically
43:49
a theory, a preliminary design, and then
43:52
they say, hey, browser vendors, go implement
43:54
this. Go, like, kick the tires on
43:56
this. And the browser vendors. Go, like,
43:59
kick the tires on this. And the
44:01
browser vendors will like, kick the tires
44:03
on this. And the browser vendors will
44:05
also invite other vendors, instead, we're going
44:08
to put it behind. basically flags where
44:10
we're at Chrome calls origin trials, which
44:12
if you're a specific domain, you get
44:15
to opt into these features, which is
44:17
an interesting point about evolution of how
44:19
we do things as well. But they
44:21
write the first design, then they say,
44:24
go kick the tires on this, and
44:26
then they go back and they change
44:28
the design based on the feedback they
44:31
got from kicking the tires on it.
44:33
And that is the design process, right?
44:35
That is the whole, that's how it
44:37
works. It's an iterative thing. The idea
44:40
that this was ever not iterative, I
44:42
think was, is incorrect. I think it
44:44
was an incorrect framing of the situation
44:47
and the juxtaposition of should you do
44:49
this? Like, no, you should do both,
44:51
right? You should sit down and think
44:53
about your API until you have a
44:56
few too many, I don't know, right?
44:58
You'll write it. We will do Pajination
45:00
in this way, and this is how
45:03
it will work for our data. And
45:05
you'll have a whole bunch of, I
45:07
don't know, will it work that way?
45:09
You'll have a whole bunch of questions,
45:12
and at some point you've got to
45:14
say, I have enough questions where I
45:16
can go experiment now, I can go
45:19
prototypes, you think, go prototypes, you think,
45:21
go prototypes, you think, go, go prototypes,
45:23
you think, go, and you do some
45:25
prototyping, so you think, so you think,
45:28
you think, I can go prototypes, so,
45:30
so, you think, I can go prototypes,
45:32
so, so, you think, you think, I
45:35
can go prototypes, so, so, you think,
45:37
you think, I can, so, I can,
45:39
I can, I can, I can, I
45:41
can, so, I can, so, I can,
45:44
I can, I can, I can, I
45:46
can, I can, and, and, I can
45:48
go, I can go, I can go,
45:51
and, I don't think any of us
45:53
are saying, just sit down and spend
45:55
six months doing a design. I think
45:57
that would be incorrect to do from
46:00
a design, API design perspective. Instead, it's
46:02
sit down, do some writing, go build
46:04
some stuff, use what you learn from
46:07
building that stuff to go do more
46:09
writing. and do this back and forth
46:11
and back and forth until you have
46:13
something where you're like, yes, I understand
46:16
the problem space, I understand what we're
46:18
trying to achieve, I've documented and articulated
46:20
what we're trying to achieve, and here
46:23
is a solution that will solve whatever
46:25
problem we're trying to solve with this
46:27
API. Agreed. So back to the two
46:29
weeks thing, I think in the past
46:32
I have spent like about two weeks
46:34
trying to do a similar sort of
46:36
thing, and just like seeing where I
46:39
get to where I get to with
46:41
that. So kind of time boxing it
46:43
where it's not like two weeks of
46:45
solid work but it's two weeks here
46:48
and there trying to give time to
46:50
flash out like what what would this
46:52
API look like and so as I
46:55
mentioned I'm familiar with open API so
46:57
I will reach for that if it's
46:59
an H2P API and so I will
47:01
start writing what the spec kind of
47:04
looks good and then I'll put it
47:06
into like an API portal and see
47:08
what it would look like. like with
47:11
a nice pretty UI, then I would
47:13
throw it into some code generators from
47:15
different languages. I'd say, okay, does the
47:17
code that it generates look about, right?
47:20
And then I'd actually take that spec
47:22
and put it into, so Stoplight Avital
47:24
called PRISM, which takes an open API
47:27
spec and generates a mock server that
47:29
returns generated data based on what your
47:31
spec says. So if you say any
47:33
string can be returned from the same
47:36
point, or in this field, it will
47:38
return you any string and that includes
47:40
emologies that includes all sorts of chaos
47:43
strings then you're like oh no no
47:45
okay I actually need to scope this
47:47
down a bit and going through that
47:49
iterative process has yeah massively helped because
47:52
it's not until like I've taken that
47:54
spec and actually put it into real-world
47:56
usage I'm like oh yeah that this
47:59
is really horrible to integrate with it's
48:01
not until you're actually playing around with
48:03
those things that you need that you
48:05
need that iterative process of actually understanding.
48:08
Yeah, I think there's layers of it
48:10
too. I think where you pointed out
48:12
there of like the, when I write
48:15
down, when you sit down and write
48:17
the open... but I was backing like,
48:19
I can return any string or any
48:21
number or any whatever it is, right?
48:24
It's useful to be able to look
48:26
at that and see any and then
48:28
just generate random blobs and you look
48:31
at it and be like, well, this
48:33
is clearly wrong. Why is this wrong?
48:35
How do I constrain this further? So
48:37
it's less wrong in going through that,
48:40
going through that habits. I think too
48:42
that winds up with you having to
48:44
think about your data that your. returning
48:47
to the user or to the application
48:49
at the end of the day a
48:51
little bit more deeply where I think
48:53
people just kind of love to happy
48:56
path it. I think this is kind
48:58
of like a, well what happens when
49:00
things go wrong or what happens when
49:03
your assumptions are incorrect? I think that
49:05
that helps a lot because we love
49:07
shortcuts as people. So I think our
49:09
brains like to do shortcuts and think
49:12
about the happy path. almost all of
49:14
the time, and that kind of patched
49:16
the not happy path in after the
49:19
fact, instead of just thinking about this
49:21
all as, you know, these are just
49:23
different paths people are going through. I
49:25
think even the framing of happy path
49:28
is maybe wrong, because I feel like
49:30
the happiest you are is when something
49:32
goes wrong and the recovery process is
49:35
a smooth one, right? Like, oh, there's
49:37
an error or a bug that surfaced,
49:39
and you and the way you resolve
49:41
it is just seamless. I feel like
49:44
that's even better at the end of
49:46
the day than just using an API
49:48
that has a good happy path, right?
49:51
Or building an application has a good
49:53
happy path. It's like, yeah, no, like,
49:55
even when things went wrong, this was
49:57
a joy to work with. I think
50:00
that really shows the mark of something
50:02
good. I think that also has a
50:04
good impression on people. Yeah, I actually
50:07
think the happy path is like, and
50:09
the design and implementation is the boring
50:11
part. It's the boring part. I mean,
50:13
especially I think that's part of also
50:16
why like a lot of people like
50:18
the happy path, which is why in
50:20
go we have this forever conversation around
50:23
error handling is because I think we
50:25
also, not just in web APIs, but
50:27
also in other APIs, we don't want
50:29
to have to think about these other
50:32
paths or error paths. and whatnot. I
50:34
think that winds up getting surface in
50:36
our APIs as well, because then I
50:39
think there's always that question of when
50:41
you're building an HDB server, if you
50:43
get an error from something you've called,
50:45
and go, but I think in any
50:48
other language, like, what do you do
50:50
with that error? Where does it, is
50:52
this an error that gets surface to
50:55
the user? How do you know if
50:57
it's a user surfaceable or like a
50:59
consumer surfaceable error? And if it's not,
51:01
what do you do with it? What
51:04
if it's crucial information for debugging why
51:06
something's wrong with somebody's account? How do
51:08
the ops people get access to that
51:11
information? Right there's all of these questions
51:13
they have to start asking when it's
51:15
just like, yeah, I have to actually
51:17
do something at the dead end of
51:20
being able to return an error. Like
51:22
you can't return an error from an
51:24
HDDB handler. So like what do you
51:27
do with it? And that informs everything
51:29
else down the stack. But if you
51:31
don't take the time to think about
51:33
that path, then you just, I don't
51:36
know, maybe just shove it in the
51:38
HDB body and send it back to
51:40
the user and you're like, oh no,
51:43
whatever, right? And it's also thinking about
51:45
the impacts of those sorts of things.
51:47
So say for instance, you've, you're like
51:49
a grocery delivery app and you have
51:52
taken the money that failed to put
51:54
the order in. get reversed. How quickly
51:56
can it get reversed? Like, is someone
51:59
now out of 100 quid and they're
52:01
now unable to buy another set of
52:03
groceries because the money's out of the
52:05
account and they don't have any left?
52:08
I was thinking about those sorts of
52:10
areas and how do you handle those
52:12
things as well? It was a thing
52:15
that recently did where we were changing
52:17
some permissions on some Kitor briefos. And
52:19
we removed like lots of access. and
52:21
then added the access back in a
52:24
second go instead of adding the new
52:26
access and then removing. maximum access, if
52:28
that makes sense. So we're trying to
52:31
reduce privilege from like everyone to a
52:33
subset of people. And because we did
52:35
the wrong way around, it broke a
52:37
load of things. It's thinking about how
52:40
do you do things in the right
52:42
way that either can be recovered from
52:44
or maybe some things like you have
52:47
to just say, sorry, someone I'm wrong
52:49
and we can't deal with it and
52:51
maybe try again and maybe it'll work,
52:53
maybe it won't. And yeah. Yeah, we
52:56
have a fun air case like one
52:58
of the things I build is like
53:00
a the company I work for runs
53:03
ad auctions, right? So we were reporting
53:05
on ad auctions and so we have
53:07
like a reporting API and sometimes queries
53:09
take longer than you think they will
53:12
right and we've already done all this
53:14
work and it's timed out and so
53:16
instead of just throwing away all that
53:19
work when there's a timeout error we
53:21
return an error that has like basically
53:23
an identifier and it says like hey
53:25
you can continue your query here and
53:28
then you send that back in like
53:30
those those kind of paths are it's
53:32
just really nice to handle things and
53:35
not throw things away that you've already
53:37
done. Yeah I think I think that
53:39
leads into a point that I want
53:41
to make which is around like one
53:44
I think one of the core things
53:46
that you need to design when you
53:48
first start designing your application is what
53:51
is your transactional unit in your API?
53:53
Right, what are, and I think most
53:55
of the time people don't think about
53:57
this at all, so they make their
54:00
transactional unit, their transfer level transactional unit,
54:02
so that's an HCTP request response, or
54:04
GRPC request and response, or a GraphQL
54:07
query and response. And I think that
54:09
that is almost always wrong. I think
54:11
that's always like the incorrect approach to
54:13
have, because I think as you just
54:16
said, Ian, with your... Timeouts, right? A
54:18
timeout is a transfer level problem, right?
54:20
That's a problem of whatever transfer protocol
54:22
I'm using, it... doesn't know like at
54:25
some point you got to be like
54:27
I don't is this thing dead it's
54:29
something might have just died and I
54:32
got a snap a connection for whatever
54:34
reason but that is orthogonal to your
54:36
a your application actually processing something and
54:38
sometimes it might be if the connection
54:41
snaps then yes I do want to
54:43
cancel out that transaction But I think
54:45
a lot of the time, no. And
54:48
I think that also adds an extra
54:50
constraint that you might not want to
54:52
have that will constrain you in the
54:54
future. For example, before I mentioned how
54:57
an API might be designed for transactional
54:59
workloads, but you might want to start
55:01
using it for analytical workloads. Well, one
55:04
of the differentiators between transactional analytical analytical
55:06
analytical is how long until something times
55:08
out. When you're doing an analytical query,
55:10
that could take minutes, hours, days, days
55:13
to run. to handle that for the
55:15
same exact query just because you're querying
55:17
different types of data, querying something in
55:20
a different way, whereas if you just
55:22
build it so that your transactions of
55:24
your application don't have to mask the
55:26
transactions of the transfer protocol, you can
55:29
wind up with just using the same
55:31
API and just being like, okay, we'll
55:33
turn off, either turn off. Timeouts completely
55:36
or return me a response right now
55:38
and give me a URL where I
55:40
can go check the status of it
55:42
and then I can go retrieve the
55:45
response later. And you have to make
55:47
no changes to your application to change
55:49
for those different use cases. This is
55:52
just a slight change in your transfer
55:54
and how the transfer works. Or I'll
55:56
start a query that might be expensive
55:58
using HDDP, but I'll actually grab the
56:01
results using GraphQ, which could be an
56:03
interesting use case because then you can.
56:05
query, you can say, oh, I actually
56:08
only want these fields, which is much
56:10
more expressible in graphic well than it
56:12
is in HDDP most of the time.
56:14
So it opens up all these different
56:17
interesting possibilities for what you can do,
56:19
but you can only do that if
56:21
you started with the idea that your
56:24
application transaction is separate from your transfer
56:26
transaction. There's a whole bunch of benefits
56:28
that you get from that. there is
56:30
a inevitable question of what is the
56:33
actual transactional boundary of my APIs, you
56:35
know, transactions or my APIs requests and
56:37
responses or whatever you want to call
56:40
them. And there's also a big question
56:42
of how do you actually implement that?
56:44
Because in languages like, go, there is
56:46
an assumption that your application fits within
56:49
an HDDP transaction. Sort of. I guess
56:51
technically you can keep the go routine
56:53
going even after you've returned a response
56:56
to the user, but that's also sort
56:58
of weird and sort of violates the
57:00
way that most people think about how
57:02
the go routine you get for an
57:05
ACB request is supposed to work. But
57:07
these are things you have to start
57:09
thinking about and how you're actually going
57:12
to go about implementing it. But I
57:14
think that's a very crucial thing. And
57:16
I think you got to decide up
57:18
front is do I want my application
57:21
transaction to match my transfer transactions? And
57:23
if I do, here's the big ball
57:25
of stuff that I'm getting, all these
57:28
extra constraints I'm getting, and if I
57:30
don't, where are the boundaries of my
57:32
application transaction? Or I guess, API transaction,
57:34
but yeah. Okay. So, talked about prior
57:37
art. I feel like we talked about
57:39
documenting things in there as well. Maybe
57:41
we should talk about some concrete things.
57:44
I think some of what we talked
57:46
about as concrete, but maybe some more.
57:48
concrete's more implementable things. So, well, this
57:50
isn't exactly concrete. Well, I do think
57:53
one of the big mistakes people make
57:55
when they go to, like, decide something
57:57
is they go into with the expectation
58:00
that it'll last forever. And maybe there's
58:02
concrete recommendations that come out of this,
58:04
but like, I do think you need
58:06
to go into things with the expectation
58:09
that, like, this will change or this
58:11
will die, right? Well, it won't always
58:13
be here. And I think, um, also,
58:16
think and look. more generally like you
58:18
in your job are probably not going
58:20
to be there forever. So what can
58:22
you do to try and build a
58:25
thing that can outblast you and your
58:27
team's involvement but also like there's a
58:29
don't know if it's a saying or
58:32
just a thing that you'll throw around
58:34
like every year like you should be
58:36
trying to automate yourself out the job
58:38
you had last year to try and
58:41
make it so you're like doing better
58:43
more interesting things and you get rid
58:45
of the load of the stuff and
58:48
similarly like APIs and stuff they should
58:50
be evolving and getting rid of the
58:52
old craft and like the world changes
58:54
around us and there will be new
58:57
things that it needs to do or
58:59
new domain models to actually understand and
59:01
retrofit and how do you get rid
59:04
of an old thing, what also not
59:06
breaking everyone horribly. Yeah. I think, interestingly,
59:08
I don't necessarily have a problem with
59:10
people thinking that something will last forever.
59:13
I think the problem I usually have
59:15
is people designing as if something will
59:17
last forever, but not actually designing as
59:20
if it'll last forever, right? Because you
59:22
can make things that effectively last forever
59:24
by having forward and backward compatibility, right?
59:26
HDML and CSS are good examples of
59:29
this. And to some degree HDDPP, but
59:31
that... puts a sort of floor on
59:33
how you design something, right? Like when
59:36
you talk about HDML and CSS being,
59:38
you know, backwards compatibility is, you know,
59:40
usually quite easy to get because it
59:42
just means that once you name something,
59:45
you just don't change it ever, right?
59:47
That thing means that thing that it
59:49
meant, and if I want to have
59:52
a new thing, that might mean something
59:54
similar, I need a new name for
59:56
it. And that gives you backwards compatibility.
59:58
Right, when I have something old that's
1:00:01
calling the new thing, and it gets
1:00:03
some data back, what can it do
1:00:05
with it? And with HGML and CSS,
1:00:08
we have four. compatibility because when a
1:00:10
application or when something sees something that
1:00:12
doesn't understand, it ignores it. And we
1:00:14
define the ignore case as something that
1:00:17
will not break everything. So for example,
1:00:19
with HTML, say you, and this is
1:00:21
actually how we got custom elements, and
1:00:24
HTML, if you have an element type
1:00:26
that you don't understand. You just pretend
1:00:28
it doesn't exist, but you also like
1:00:30
its content type becomes the type of
1:00:33
the content it contains. Which is very
1:00:35
useful, because that means that when we
1:00:37
came up with custom elements, now you
1:00:40
have custom elements, you can define new
1:00:42
elements, and you can progressively enhance and
1:00:44
get the functionality you want to get
1:00:46
eventually. and we didn't have to go
1:00:49
break old stuff. Yeah, like the the
1:00:51
idea of forward compatibility isn't necessarily that
1:00:53
the new functionality is going to work
1:00:56
in the old thing. That's a much
1:00:58
much much harder thing to do and
1:01:00
something you really only do with code
1:01:02
on demand. It's instead for what that
1:01:05
old thing understands, it will interpret this
1:01:07
in a reasonable way. And I think
1:01:09
backwards compatibility is the the other part
1:01:12
of that where it's like, you know,
1:01:14
a new thing that is consuming. Or
1:01:16
like, you know, you produce new data
1:01:18
and the old thing can still work.
1:01:21
You haven't broken something in a way
1:01:23
where that old thing's going to get
1:01:25
confused. So forward a backward compatibility kind
1:01:28
of boiled down to which perspective you're
1:01:30
looking at it from, where backward compatibility
1:01:32
is from the producer of the data,
1:01:34
and forward compatibility is from the consumer
1:01:37
of the data. Hey there. So this
1:01:39
is Christian Post, and I just wanted
1:01:41
to clarify what I said there, because
1:01:44
I got it slightly wrong. So the
1:01:46
idea of backwards compatibility is that you
1:01:48
can have a new thing, consume data
1:01:50
information, whatever, that was meant for an
1:01:53
older version of it. The idea of
1:01:55
forward compatibility is that an older version
1:01:57
of a thing can consume data meant
1:02:00
for the newer version of that thing.
1:02:02
So here's an example that we can
1:02:04
use in Go. So Go has the
1:02:06
Go One compatibility guarantee. This is a
1:02:09
backward compatibility guarantee in that Go code
1:02:11
that was written for an older version
1:02:13
of the Go compiler will still compile
1:02:16
with newer versions of the Go compiler.
1:02:18
So what I just said, the newer
1:02:20
version of the thing can compile
1:02:22
something that was met for the
1:02:24
older version of it. Go does
1:02:26
not, however, have a forward compatibility
1:02:29
guarantee. So you can't take newer
1:02:31
Go code, or Go code meant
1:02:33
for a newer Go compiler, and
1:02:35
necessarily compile it with an older
1:02:37
Go compiler. So if we use
1:02:39
numbers here, you can compile code
1:02:41
that was built for Go1.10 with
1:02:44
a Go1.20 compiler. But you can't
1:02:46
necessarily compile code that was meant
1:02:48
for a 1.20 compiler with a
1:02:50
1.10 compiler. Hope that clears things up.
1:02:53
Back to the show. But
1:02:58
I think if you if you
1:03:00
design into your API that base
1:03:02
level of understanding of saying I'm
1:03:04
going to make this forward and
1:03:07
backward compatible and I'm going to adhere
1:03:09
to that Then I do think what you
1:03:11
build can last forever But there's small
1:03:13
constraints you have to put around
1:03:15
it. Let me give you the
1:03:17
situation I'm thinking of when I
1:03:19
say this so I used to
1:03:21
work for a company called Time
1:03:23
Hop They would show you your
1:03:25
photos you took them the previous
1:03:27
years, right? And you know, our
1:03:29
API API, like say Twitter, Twitter
1:03:31
changed a lot of their APIs
1:03:33
where you basically could no longer
1:03:35
pull people's tweets, right? And our
1:03:37
API that served our clients was
1:03:39
designed in such a way that
1:03:41
we had no way to signal like
1:03:44
this doesn't exist anymore, right?
1:03:46
So when I'm thinking of
1:03:48
it more like, like I don't
1:03:50
know, not only it won't exist
1:03:52
all the time, but like, I don't
1:03:55
know how I'm saying. I want to say
1:03:57
this. Like I think you do need to
1:03:59
build in like signals that say like
1:04:01
this doesn't work, right? I think that's
1:04:03
part of the, I mean, when I said
1:04:06
like the forever, that's part of
1:04:08
it too, of like the forward
1:04:10
and backward compatibility of it, of
1:04:12
like one of the ways that
1:04:14
you get this, which is what
1:04:16
protocol offers to, is that basically
1:04:18
everything is optional. You can't
1:04:20
have any required things because as
1:04:22
soon as you have a required thing,
1:04:25
you can't add new required things without
1:04:27
breaking backward compatibility. And it makes everything
1:04:29
a giant mess. So what you need
1:04:31
to do is say, okay, well, everything
1:04:34
is optional, which also takes care of
1:04:36
the case. You just talked about E.M.
1:04:38
where it's like, this thing might not
1:04:40
be here. And now your application has
1:04:43
to figure out what it's going to
1:04:45
do. to fail. And this is where
1:04:47
you get that for compatibility idea from
1:04:49
of, yeah, you don't get the new
1:04:52
functionality, but if eventually you're like, okay,
1:04:54
well, we just can't return this type
1:04:56
of data anymore, then your application had
1:04:58
to when it was built have to
1:05:00
deal with the fact this thing might
1:05:02
not be there because you've said it's
1:05:05
optional because everything is optional in the
1:05:07
API. And I think that alone is
1:05:09
a really hard constraint for people because
1:05:11
you have to really start thinking about things
1:05:13
in a different way. are very different,
1:05:15
which is where it's, and I think
1:05:17
that's the tradeoff here in the, you know,
1:05:20
if we're talking about the concrete aspect of
1:05:22
this, of you can in fact design as
1:05:24
if your API is going to last forever,
1:05:26
but there's a, there's a kind of floor
1:05:28
of the things you must consider if you're
1:05:30
going to do that. And there's a floor
1:05:33
of what you can do that you have
1:05:35
to consider, right? As we just said, it's
1:05:37
like. You have to basically everything has to
1:05:39
be optional. You have to come up with
1:05:41
new names for things. You can't really repurpose
1:05:43
names unless you have namespacing or something like
1:05:45
that, which means you have to introduce some sort
1:05:47
of namespacing mechanism. You have to make sure
1:05:50
that old clients are built in a way
1:05:52
that when they encounter new information, it doesn't
1:05:54
break them. They don't throw errors. They understand
1:05:56
how to gracefully handle that, which means you
1:05:58
have to plan for that. up front,
1:06:00
which means your data modeling has to
1:06:02
be such that you can actually plan
1:06:05
for how that sort of thing will
1:06:07
work up front. There's a huge amount
1:06:09
of stuff that you wouldn't do. So
1:06:12
if you want to design something, it'll
1:06:14
last forever. You can, it's just more
1:06:16
work. And if you're not, you should
1:06:19
explicitly design it, not to last forever.
1:06:21
And if you're not, you should
1:06:23
explicitly design it, not to last
1:06:25
forever, without taking on the... actual
1:06:27
constraints that will make it last
1:06:29
forever. And that's how you wind
1:06:32
up with the, we'll just slap
1:06:34
V2 on the thing and continue
1:06:36
forward or V3 or V4 or
1:06:38
V5. That's just a new name space.
1:06:40
Yeah, it's a new name space, but
1:06:42
we didn't think about it. So it's
1:06:45
actually real messy because like, yeah, that's
1:06:47
the thing too, right? When you do
1:06:49
concretely out of V2. It's like, did
1:06:51
everything change? Not everything changed. Only
1:06:53
some of the things changed, because
1:06:55
you didn't wait for everything to
1:06:57
need to change before you did
1:06:59
this V2. So it's like, some
1:07:01
things still work the same, but
1:07:03
other things work in a different way,
1:07:06
and now it's just super duperty
1:07:08
confusing. So I think that is
1:07:10
a good, pretty, duperty, confusing. So
1:07:12
I think that is a good
1:07:14
decision point you need to make
1:07:16
from the beginning, or an infinite
1:07:18
thing. Does this thing have a... a
1:07:20
shelf life or does it not? And then
1:07:22
based on whichever decision you want
1:07:24
to make, you pick the right set
1:07:27
of constraints to actually enable
1:07:29
that, and you document those
1:07:31
constraints. I think for a
1:07:33
lot of people, probably designing
1:07:35
finite things is where we should start
1:07:37
for now, because I think trying
1:07:39
to design infinite things is
1:07:41
much more challenging given the state
1:07:44
of the industry at the moment.
1:07:46
And I think it's much better to design
1:07:48
things that say, hey, this won't last forever.
1:07:50
And if your consumers are like, we really
1:07:52
want something that'll last forever, then you
1:07:55
probably need to reconsider what you're building.
1:07:57
And then you might need to take
1:07:59
that. infinite path instead. But
1:08:01
I also think that someone needs to
1:08:04
write down or maybe we'll do
1:08:06
a podcast episode about what does
1:08:08
it look like to define to
1:08:10
design a forever API. So I
1:08:12
think they'd be really interesting. We
1:08:15
could go through some use cases of
1:08:17
like HDML and CSS are very
1:08:19
good examples. HDCP and SMTP I
1:08:21
think are also very good
1:08:24
examples of things that are just
1:08:26
have been around forever. will
1:08:28
perceiveably be around forever
1:08:30
from this point. Yeah, so
1:08:32
we really haven't touched on much
1:08:35
actual concrete things. Do we actually
1:08:37
have concrete things we can we
1:08:39
can share? Like, I do feel
1:08:42
like it's always, it depends. Well,
1:08:44
I guess, oh, what do we
1:08:46
mean by concrete then? Actually, I
1:08:48
like, I'm a new dev, I'm
1:08:51
building an API, give me a
1:08:53
checklist, you know? I think one
1:08:55
that I haven't regretted it.
1:08:57
keeping my like application
1:09:00
and transfer layers separate
1:09:02
for having a separate set of
1:09:04
say go types for my
1:09:07
web layer for the thing
1:09:09
that is actually returned and
1:09:11
what is the actual core
1:09:14
API implementation. So sometimes called
1:09:16
like a service or domain
1:09:19
layer. Sometimes there's a
1:09:21
separate yeah business logic. And
1:09:23
in fact there was one
1:09:25
previous jobs. the other team
1:09:27
who did this really well
1:09:29
and so well that they had
1:09:32
a code base that they deployed
1:09:34
both as a deployed Java web
1:09:36
service as well as also shipping
1:09:39
it into AWS lambda as a
1:09:41
Java jar with very little
1:09:43
change needed because the
1:09:45
core functionality of that interface
1:09:48
and of how that
1:09:50
worked they needed to do
1:09:52
a little bit of wiring
1:09:54
to make it actually. be
1:09:57
deployable for both those
1:09:59
options. web interface was the same and
1:10:01
it gave them that flexibility and proved
1:10:03
that it is straightforward to do when
1:10:05
you've done a load of work to
1:10:07
make it straightforward to do and is
1:10:09
one of those things that does end
1:10:11
up with a bit more duplication you
1:10:14
have to spend a bit more time
1:10:16
converting between types in the different layers
1:10:18
it gives you that flexibility and especially
1:10:20
as we're saying earlier where your database
1:10:22
schema will change you will want to
1:10:24
evolve your API. So at some point
1:10:26
those two things are definitely not going
1:10:28
to be one to one. And then
1:10:30
even like going a little bit further
1:10:32
and having like a domain object where
1:10:35
it's like completely separate to how it's
1:10:37
stored in the database and what the
1:10:39
web is. What is the underlying actual
1:10:41
thing and what the actions that are
1:10:44
happening within it? And in particular on
1:10:46
the implementation side, trying to make it
1:10:48
so you don't import any other packages
1:10:50
in your domain layer to make it
1:10:52
so it is pure go. job or
1:10:55
whatever and gives you like a really
1:10:57
really clean idea of this is the
1:10:59
business logic and these are the things
1:11:01
that should be happening and give
1:11:03
you that really clean separation
1:11:05
then can be consumed as a
1:11:07
web up or otherwise. Yeah I
1:11:10
do think there's some resistance there
1:11:12
like people don't want to have
1:11:14
three of the same type with
1:11:16
nearly the same fields maybe different
1:11:19
Jason tags to start and I do
1:11:21
get that resistance, but in the long
1:11:23
term I 100% agree that that is
1:11:25
worth it. I also think to a
1:11:27
degree if you wind up feeling that
1:11:29
way, then I don't think you've actually
1:11:32
defined, I don't think you've designed
1:11:34
an API in the sense that we've
1:11:36
been talking about it, I think
1:11:39
you've designed a query layer for
1:11:41
your database. Which in some cases
1:11:43
is the right thing to do, like, that's
1:11:45
not necessarily wrong. But it
1:11:47
will evolve and eventually probably not
1:11:50
be a query later for your
1:11:52
database Yeah,
1:12:00
I do feel like this whole concrete
1:12:02
idea is hard to give you a
1:12:04
checklist. Like it is hard to, like,
1:12:06
yeah, I mean, when we wrote this
1:12:08
topic, I was more thinking of, like,
1:12:10
actionable things, but not, kind of like
1:12:12
what I just said around, like, don't
1:12:15
use resources, but it's like, I don't
1:12:17
know, there's a lot of any wants
1:12:19
in there, so like, use them if...
1:12:21
if that works, but look out for
1:12:24
these pitfalls. Like I think that's, that's,
1:12:26
that's, that feels concrete to me. I
1:12:28
feel like a lot of the science.
1:12:31
I mean, I think a lot of
1:12:33
what we talked about in this episode
1:12:35
as a whole has been concrete, but
1:12:38
a lot of it was for design.
1:12:40
I think this is more implementation specific
1:12:42
stuff. Or maybe not. Maybe, I guess,
1:12:44
resource is still part of your design
1:12:47
on less part of your input. Right.
1:12:49
Like, we've. We've done a lot to
1:12:51
try and talk about APIs without ever
1:12:54
really talking about APIs, right? I think
1:12:56
that was kind of my last point
1:12:58
there too, where it's like a lot
1:13:01
of the time we spend time arguing
1:13:03
about things that just don't matter at
1:13:05
the end of the day. Like, yeah,
1:13:08
if you build an API that only
1:13:10
ever returns 200, 400, and 500, okay.
1:13:12
Like, does that actually make that big
1:13:14
of a difference? Some people might be
1:13:17
a little bit annoyed, but it's proven
1:13:19
out that you don't have to like.
1:13:21
Graphcule was insanely popular. Yeah, I mean,
1:13:24
Graphcule is insanely popular and it only
1:13:26
uses 200s, right? And yeah, I'm sure
1:13:28
people can sit there and get mad
1:13:31
about it and argue about it. We
1:13:33
talked about that in one of the
1:13:35
previous episodes. We did. I'm sure you
1:13:37
argued about Ten Los episodes. We did.
1:13:40
I mean, I know January was a
1:13:42
long time ago, Jamie, but you were
1:13:44
on that episode where we argued about
1:13:47
this, and I was in support of
1:13:49
the 200. And Dylan was like, it's
1:13:51
wrong. I think that proves out that
1:13:54
you can build stuff that's still useful,
1:13:56
that still does what it needs to
1:13:58
do without having to do things perfectly.
1:14:00
It's really about, you know, building stuff,
1:14:03
learning from you. past mistakes and try
1:14:05
to do things right in the future.
1:14:07
But I think so much of our
1:14:10
rhetoric is around this idea of correctness
1:14:12
about what's technically correct, that we lose
1:14:14
sight of, you know, what all of
1:14:17
this was about in the first place,
1:14:19
right? HDP is meant to be a
1:14:21
transfer protocol for hypertext or hyper media,
1:14:24
right? It's meant to be disability to
1:14:26
have in self-describing messages, you get some
1:14:28
bit of hyper media, which is media
1:14:30
plus controls. to the end user, right,
1:14:33
so that they can build their application
1:14:35
and do what they want to do.
1:14:37
If what your building has accomplished that,
1:14:40
then great. You've done it well. And
1:14:42
we should talk more about how to
1:14:44
accomplish it better for different contexts rather
1:14:47
than trying to say, ooh, you returned
1:14:49
a 302 and you should have really
1:14:51
returned a 303. We're saying, oh, you
1:14:53
returned a 204? That probably should have
1:14:56
been a 200. Like, who cares? Like,
1:14:58
stop it. Please stop it. Talk about
1:15:00
something that is more valuable than that.
1:15:03
Like, how you're going to separate your
1:15:05
business layer from your database layer? Because
1:15:07
that... is much more important than whether
1:15:10
you're returning 200 or 204 at the
1:15:12
end of the day. That's something that
1:15:14
you don't want to mess up. That
1:15:16
felt like a very not Chris-like take,
1:15:19
but I'm here for it. Why does
1:15:21
that feel like a not just like
1:15:23
take? Can't explain it. Yeah. Listeners will
1:15:26
agree, I guarantee. But I'm here for.
1:15:28
I think you're completely right that like
1:15:30
bike shedding shedding shedding over. your status
1:15:33
codes and your paths. Like at the
1:15:35
end of the day, it doesn't matter
1:15:37
as much as building it, learning from
1:15:40
it, maintaining it. I think that's always
1:15:42
been, maybe the way I've expressed these
1:15:44
ideas has been not as, not as
1:15:46
sharp as I would like them to,
1:15:49
but that's always been, you know, I'm,
1:15:51
I tend to be, even though I
1:15:53
don't like this word, pragmatic about all
1:15:56
of this, like, build something that is
1:15:58
useful. problem has been in the past
1:16:00
and continues to be, when we build
1:16:03
something that is harmful or not as
1:16:05
useful as we wanted it to be,
1:16:07
and we refuse to learn from those
1:16:09
lessons, I think that's where my problem
1:16:12
comes in. And sometimes that does come
1:16:14
in the form of, yes, you should
1:16:16
sit down and learn HDP and you
1:16:19
should understand what these status codes are
1:16:21
because that's once again learning from prior
1:16:23
art and you might find something that
1:16:26
is useful. But I do think there
1:16:28
is a difference. I will say a
1:16:30
place where I have personally changed, is
1:16:32
I think there's a difference in how
1:16:35
you actually do that. I don't think
1:16:37
the time to do that is when
1:16:39
you're actively trying to build something, right?
1:16:42
I think when you're actually trying to
1:16:44
build something, you should focus on actually
1:16:46
trying to build the thing. And in
1:16:49
that case, if all you understand right
1:16:51
now is 200, go use 200. Don't
1:16:53
spend your time trying to learn what
1:16:56
all of the 200 codes are and
1:16:58
how you should use them. you're probably
1:17:00
not going to be able to learn
1:17:02
as much as you would if you
1:17:05
were in a more exploratory mode. Just
1:17:07
put a pin in all of that
1:17:09
and then later... set yourself aside some
1:17:12
time to go explore and learn some
1:17:14
prior art and then you can do
1:17:16
a deep dive on the differences of
1:17:19
the 200 status codes. And then once
1:17:21
you understand all of that, then the
1:17:23
next time you go build something, then
1:17:25
you can actually use those status codes
1:17:28
because now you understand them better. So
1:17:30
I think there's a separation here that
1:17:32
needs to happen of your learning mode
1:17:35
and your building mode. And sometimes it's
1:17:37
fine to combine them, but a lot
1:17:39
of the times you need to be
1:17:42
practical and you just need to build
1:17:44
with what you got. There is no
1:17:46
point at which you will have all
1:17:48
the information you need to build something.
1:17:51
You will always, there will always be
1:17:53
something that's like, man, I would have
1:17:55
done that better if I had that
1:17:58
knowledge. That will always be the case.
1:18:00
So you've got to figure out a
1:18:02
way of how are you going to
1:18:05
acquire that knowledge so that you're always
1:18:07
saying that, but you're not saying that
1:18:09
about the same thing over and over
1:18:12
and over again. Or you feel like,
1:18:14
oh, I understand way more than I
1:18:16
did before. I think that that's the
1:18:18
important thing at the end of the
1:18:21
day. So I do think it's extremely
1:18:23
important that people do learn HDP and
1:18:25
do learn what rest is, especially if
1:18:28
they want to call something restful. I
1:18:30
think that's... That is very important. But
1:18:32
I think that that can happen outside
1:18:35
of you doing building an API or
1:18:37
designing something, especially for work. That feels
1:18:39
like a good place to wrap this
1:18:41
thing up. I can't wait to see
1:18:44
how much I've been talking in this
1:18:46
episode. Build with what you got. Build
1:18:48
with what you got. Build with what
1:18:51
you got. I think that's, you know,
1:18:53
that at the end of the day,
1:18:55
that is the infinite perspective. So. There
1:18:58
will always be more to learn. So,
1:19:00
go learn and go learn at the
1:19:02
same time. Practice. Do your practice. Great
1:19:04
musicians don't only play concerts. They also
1:19:07
practice. We should also be doing that.
1:19:09
But yeah, that un-pops. Now there's this
1:19:11
unpop that Jamie, Jamie teased us before
1:19:14
we started recording. On the edge of
1:19:16
my seat, even though I'm standing. This
1:19:18
is gonna be. The greatest unpop ever,
1:19:21
I don't, I have no idea, he's
1:19:23
just, he told us nothing about it.
1:19:25
So, now we need to, and we
1:19:28
need to hear this unpop Jamie. And
1:19:30
I feel gutted, but I don't think
1:19:32
it's going to land quite as well
1:19:34
after that episode. We've undermined your unpop
1:19:37
accidentally, oh. I know. And so, yeah,
1:19:39
it's a say. This may not make
1:19:41
it to the final video and audio
1:19:44
and everything. My unpop is about fall
1:19:46
through the show and in particular the
1:19:48
subscriber tiers. Okay. And my unpop is
1:19:51
that there should be an additional tier
1:19:53
to remove Chris's ramps. I think we
1:19:55
leave this end. An additional tear to
1:19:57
remove my rant. I don't, I mean,
1:20:00
someone else would probably have to edit
1:20:02
that because my rants, I listen to,
1:20:04
I do listen to my rants, I
1:20:07
mean, I have to, I edit the
1:20:09
show. And most of the time, I'm
1:20:11
like, there are sometimes when I do
1:20:14
cut some of the rants into subscriber
1:20:16
only because I'm like, this does not
1:20:18
need to be part of the show.
1:20:20
So that gets dumped into subscriber only.
1:20:23
But yeah, there is actually something we
1:20:25
are working on. That will probably inevitably
1:20:27
wind up removing some of my rants
1:20:30
just because I do talk for five
1:20:32
minutes at a time and This this
1:20:34
new addition of all-through where we're trying
1:20:37
to get off the ground is time
1:20:39
constrained So the people that talk the
1:20:41
most are the ones that will probably
1:20:44
get cut the most but there is
1:20:46
this you know, I guess the the
1:20:48
background of it is If
1:20:52
you want to hear the rest
1:20:54
of that thought and a whole
1:20:56
bunch of other bonus content, head
1:20:58
on over at fall through dot
1:21:00
fm slash subscribe and sign up
1:21:02
today. So I guess in a
1:21:04
roundabout way, there will likely be
1:21:06
a version of the podcast that
1:21:08
has many of my rants cut
1:21:10
out. Or at least trim down
1:21:13
to something more reasonable. Which is
1:21:15
a shame because, but... they are
1:21:17
generally valuable and like I'm making
1:21:19
light of the fact that they
1:21:21
are good. But also like a
1:21:23
short version of the podcast does
1:21:25
sound interesting and I think it
1:21:27
makes sense to be a subscriber
1:21:29
or anything because or a supportive
1:21:31
thing because like it's going to
1:21:33
take even longer to edit but
1:21:36
it already takes you a lot
1:21:38
of time and a lot of
1:21:40
energy to go through it and
1:21:42
also I can't imagine even going
1:21:44
through and being like okay of
1:21:46
all this. amazing content. How much
1:21:48
do we get rid of? Yeah,
1:21:50
I mean, interestingly though, this is
1:21:52
always the funny part because I
1:21:54
think people always assume that the
1:21:57
video version takes longer to edit
1:21:59
than the other. audio version, but
1:22:01
it doesn't. The video version is
1:22:03
actually takes less time to edit
1:22:05
than the audio version because in
1:22:07
the audio version I cut out
1:22:09
all of the ums and ahs
1:22:11
and all of that. In the
1:22:13
video version I just don't bother.
1:22:15
I could, right? You could cut
1:22:18
out all of that. You could
1:22:20
use an AI tool to cut
1:22:22
out all of that and then
1:22:24
you just have a whole bunch
1:22:26
of jump cuts, but I don't
1:22:28
really want to watch a podcast
1:22:30
where it's just like a ton
1:22:32
of jump cuts happening all of
1:22:34
the time. As a video person
1:22:36
I think it's fine if you
1:22:39
can if you keep all those
1:22:41
pauses I think it gives you
1:22:43
a better experience of the show
1:22:45
in general too because it makes
1:22:47
the video version show different but
1:22:49
that's why the video version doesn't
1:22:51
take as long as the audio
1:22:53
version and also interestingly it won't
1:22:55
take us much more time to
1:22:57
edit to get this third version
1:23:00
of the show because when I
1:23:02
make the first version of the
1:23:04
show it's really about me just
1:23:06
building at my workflow when I
1:23:08
make I do one kind of
1:23:10
pass for the show where I
1:23:12
sit down, I went back to
1:23:14
editing on one X-speed, I sit
1:23:16
down, I listen to it, and
1:23:18
I think as I'm editing, as
1:23:21
I'm going through the process, what
1:23:23
is the show about? What are
1:23:25
we trying to accomplish here? What
1:23:27
is the storyline? And I kind
1:23:29
of go through and figure that
1:23:31
out as we're going through, and
1:23:33
I mark up in audition, which
1:23:35
is our editing software, I mark
1:23:37
up in there, this part supporter
1:23:39
only, this part's a core story
1:23:42
line, this part of course story
1:23:44
line, the free version and eventually
1:23:46
the still playing with this name,
1:23:48
but I'm thinking about calling it
1:23:50
fat free fall through. So when
1:23:52
we make the fat free version,
1:23:54
it's really just about doing the
1:23:56
mechanics of cutting out those extra
1:23:58
things and putting it all together.
1:24:00
So it won't actually take much
1:24:03
more to edit those, to get
1:24:05
those. It's really mostly just about.
1:24:07
having to sit down and go
1:24:09
through and build up this process
1:24:11
of figuring out what the story
1:24:13
is, which is challenging. I'm getting
1:24:15
better at it though. I do
1:24:17
have one more if we've got
1:24:19
a few minutes. Okay. We do.
1:24:21
Go for it. So one of
1:24:24
the other, is maybe not an
1:24:26
unpop and just something I want
1:24:28
to talk about, but is that
1:24:30
everyone should have an API for
1:24:32
themselves. And so I don't necessarily
1:24:34
mean a technical API, but there's
1:24:36
a thing called manual of me.
1:24:38
And we'll drop a link in
1:24:40
the show notes. But it's an
1:24:42
idea where you, like we work
1:24:45
with so many people. And over
1:24:47
time you learn like the nuances
1:24:49
of working with me, you notice
1:24:51
that I'll end up multitasking a
1:24:53
lot, in calls generally, I'll sometimes
1:24:55
get distracted with things. And Emanuel
1:24:57
in me is a way of
1:24:59
basically explaining that to your colleagues
1:25:01
and giving them like a cheat
1:25:03
sheet on how best to work
1:25:05
with you. And I found it,
1:25:08
so someone with ADHD, I found
1:25:10
it like really useful to be
1:25:12
able to share with people. how
1:25:14
it actually affects me and what
1:25:16
sort of things they will see
1:25:18
that are probably related with that.
1:25:20
So it's not potentially on a
1:25:22
technicality an API because it or
1:25:24
a contract because it describes like
1:25:26
how to work with me, but
1:25:29
it is something that I recommend
1:25:31
people doing and you don't have
1:25:33
to share it as publicly as
1:25:35
I do. It's the sort of
1:25:37
thing that it does really help
1:25:39
people with working together. That makes
1:25:41
perfect sense. Yeah, as also a
1:25:43
developer with pretty bad ADHD. There
1:25:45
are some things people do or
1:25:47
I'm like, you know, you probably
1:25:50
shouldn't do that. Like give me
1:25:52
an unlimited deadline. Don't do that.
1:25:54
Oh, yeah. This podcast. Yeah, no,
1:25:56
I think that's good. Like, I
1:25:58
mean, it does take some self-reflection
1:26:00
to be able to sit down
1:26:02
and write that, which I think
1:26:04
is the tough part. But I
1:26:06
do think being like... honest with
1:26:08
it's freeing in a way I
1:26:11
would say like I don't I
1:26:13
mean I guess I sort of
1:26:15
have a man of me in
1:26:17
that I journal every day. Less
1:26:19
than I used to. There was
1:26:21
a point in time last year
1:26:23
where I was writing a ridiculous
1:26:25
amount. Now I'm writing less, but
1:26:27
it's still a lot. But I
1:26:29
feel like that's my own internal
1:26:32
API for myself of just reflecting
1:26:34
and seeing like, oh. We're doing
1:26:36
that thing that we said we're
1:26:38
not going to do. Let's have
1:26:40
a discussion about that and try
1:26:42
to adjust it, try to change
1:26:44
it, which is just useful to
1:26:46
have even just for yourself over
1:26:48
time of being able to like
1:26:50
notice things and see things and
1:26:53
understand things better. So yeah, I
1:26:55
think it's a, whether you share
1:26:57
it with other people or not,
1:26:59
it's a useful thing to have.
1:27:01
And I understand why people might
1:27:03
not want to share it with
1:27:05
others, depending on the work environment
1:27:07
you're in. are all over the
1:27:09
place. But I do think as
1:27:11
a concept, I like it. So
1:27:14
we talked about designing an API.
1:27:16
You should also design the API
1:27:18
of you figure out what you
1:27:20
want that interface to look like
1:27:22
and then go work on making
1:27:24
that happen. I like that. That's
1:27:26
good ending. All right, on that
1:27:28
note, like subscribe, like subscribe, comment,
1:27:30
reply to us on our social
1:27:32
media. Send this mail on our
1:27:35
PO box. Yes, send us the
1:27:37
notification bell. Smash that notification bell.
1:27:39
No, it's smashed at subscribe button
1:27:41
and rain that notification bell. Yeah,
1:27:43
the YouTube's, all the fat. Should
1:27:45
we exit like a YouTube? You
1:27:47
do know that's what I'm going
1:27:49
to use now, right? Like that's
1:27:51
going to bind by me. The
1:27:53
classic, classic handover, handover from the
1:27:56
camera. Anyway, see you later y'all.
1:28:03
Thank you once again Jamie Tana joining
1:28:05
us for another great episode of of
1:28:08
Fall Through. On next week's episode, the panel
1:28:10
and I get together to talk
1:28:12
about about Fall far. We We discuss
1:28:14
how we felt about our first
1:28:16
quarter of Shipping a New podcast, the the
1:28:18
episodes that we the the segments
1:28:20
that we loved, and also some
1:28:22
behind the scenes info how how we
1:28:24
actually make this podcast, how how
1:28:26
that's evolving and changing, and and what
1:28:28
we've got planned for the future.
1:28:30
the We think you're really going
1:28:32
to love it, so make sure
1:28:35
you're subscribed make you can get notified
1:28:37
as soon as we publish. get notified
1:28:39
as soon as we publish. episode of Fall
1:28:41
Through was hosted by Chris Brando Chris
1:28:43
Brando, with co-host Ian Wester guest co -host guest co-host
1:28:45
Jamie Tana. Fall Through is is produced by
1:28:47
Chris Brando and Angelica Hill, and
1:28:49
our our are by Break Master Cylinder. It's
1:29:09
the sun. Y'all need to go
1:29:11
to therapy. Wow, I can't English
1:29:13
today. Somebody that I used to
1:29:15
go. People thought I'd go anywhere,
1:29:17
right? Everybody's going back to Java,
1:29:19
that's what I'm seeing.
Podchaser is the ultimate destination for podcast data, search, and discovery. Learn More