Transcript
This transcript was autogenerated. To make changes, submit a PR.
You. Hello and thank you all for joining my session
at Conf 42 DevOps 2023 on deploying,
building and observing sdks as a service. As a
developer of many, many years, as consumer and architect of
APIs, this is by far one of my favorite topics and
well, one that I've, I've handled a number of times
using what we're going to be talking about today. But anyway, as we
go through this session, please drop any questions, comments,
emojis into the chat or reach out to me in social media.
I'm at developersteve Coochin pretty much most places and
well, let me know what you think. Again, I will accept emoji.
Anyway, before we get too far underway, I do have a quick disclaimer.
I love tech jokes. I have a very long list of them. These are open
source jokes, so please share them around to help make folks smile.
But my joke today is why do devs prefer app dark themes?
Well, it's because light attracts bugs.
But of boots, I normally have a sound effect, but it's a few screens
away so might do that one today. But anyway, you get the idea again.
Hello, my name is developer Steve. I've been writing code,
building apps and while just geeking out and tinkering around in the
tech world for many, many years now,
as a data analyst, as CTO, as developer,
as developer advocate for more recent years.
Always just love geeking out with folks, hearing what you're all building and
well, hearing those geek out stories because that's what the industry is.
In particular, I always love hearing about those side projects because we just
came out of, well, we just came out of end of year holidays.
Hope people got to build out some really cool stuff. I actually built out a
hydro system, which I've hooked up to some IoT stuff, but I'll
talk about that one in another talk. APIs in particular
have something I've got a real soft spot for. I've been
working with them for many, many years and also working
to support them in a variety of roles as well. And APIs
for me kind of need a few different aspects to
really make them robust and well, to see a wider level
of adoption because ultimately that's kind of why we build them usually,
particularly with open ecosystems. It always blows my mind.
Run hackathons all over the world for some really big companies
and it always blows my mind just seeing some of the innovation that
innovative things that even the most
sort of regular looking APIs, I'm going to say, you know
what I mean, what people can build out some amazing experiences.
This one time I actually saw someone walk into a hackathon with a brand new
toilet and do some pretty unusually
weird and cool stuff with it. But anyway, that's a talk for another day.
But for my money, a good API really needs to provide a
valid service, because that's really, really important. Like you
expose these endpoints or expose these accesses into your platforms
or service to be able to provide some sort
of value to a developer's application, or even to
help them build out an idea they might have using your
service. And again, sometimes those can be quite mind blowing.
But having it provide not only access to a valid service,
but in a valid way is critically important to building out any
sort of longevity around an API. Of course it
has to be well documented, and we've all been here before.
The documentation doesn't lie just with the written
documentation too. But for my money, it's always also having
some sample code or some video tutorials just
to add to, say, written documentation. Don't get me wrong,
written documentation always critical. But having that video and
also sample app content available is
always great to add extra value to people
trying to build out and use your experience. Of course, integration options,
always critical to making sure you're supporting a number of widely
used platforms or different language types,
making sure that your app has some ready to
use and quick and easy ways to connect into those different platforms.
Always great to survey your user base to see what
they're looking for or even a request form. If a
particular language isn't available, someone can request it and reach out
and tell you what they want to do and how they
want to do it. Always great to get that feedback. And of course sdks,
which is what we hear about today. Now, I've spent many,
many hours, many, many hours building out and
helping support, debug and fixing manually fixing
sdks over the years. And what we're talking about today
was something I worked on a number of years ago for
big telco AAS, working out ways
to automatically generate a lot of sdks very, very quickly
using some API specs. Originally using
Swagger one, but then as the internal system sort of got upgraded,
moving along to Swagger two, and then of course open API spec.
Open app spec. Totally amazing. And if you're using the earlier
versions of Swagger, I highly recommend upgrading because
it plugs into what we're about to talk about today
a little bit better than the swagger two. It actually gives you more options with
the structure of the YAML or the JSON behind
essentially the structure of the design with the API enter
open app generator. I feel like I need like a big grand
entrance. Music we'll add that later.
Open API generator for me is one of the most amazing
open source communities I've ever contributed to or been fortunate
enough to connect with, and they're a great community, but we'll get
into that more in a little bit. In particular, what open app
generator allows you to do, and again, this is an open source community,
is load in an open API spec and be able to generate
sdks in a variety of languages really quickly.
Now, originally you start using this as a local
installable CLI. So you just brew install open app
generator, and then you can basically
generate an SDK from an open API spec,
which is where I started using it initially, essentially taking an
API product spec and then loading it into OpenAPI generator
locally, you're able to generate out an SDK really,
really quickly with documentation too, I might add.
But what's really cool is this then over the years
became a deployable containerized service, which we're going to be looking at today,
so that you could either use it locally or as an
SDK deployed as a service. But we'll get more into that as a
moment. Like I said, it also supports not
only open API specs, but also some of the legacy
Swagger one and Swagger two docs as well.
Bit of an asterisk on that one because it's going to also depend
on the associated language or platform you're looking
to generate out as to how that is then supported.
I could spend a lot of time talking about this, but I'm not going to
today because I'm on the clock
again. Please reach out and would love to connect further to sort
of talk more about that. I'm about to show you what I mean,
because this is one of my favorite parts of this open source project
and aas been running for a number of years now,
but it's like one open source project
that has the core team of organizers who do a fantastic
job and again, couldn't sing them enough praises. Please, if you're looking
to use this or you are using this, please contribute back the way you can.
Because beyond the core team, each one of these language types,
platform SDK generators
essentially has its own subcommunity underneath that. So you have like core organizers,
then you have all these that you can see on screen, which is
phenomenally mind blowing. It is a massive project
of massive undertakings and could spend hours
talking them up, but please contribute back if you can, because they do
fantastic work, particularly supporting all this. Essentially,
inside each different language and platform you have a
template that then ingests the open API spec
or swagger spec you throw in and then generates out a variety
of different sdks automatically, which is super, super cool.
The best part about this is, and while the default
templates may not be a one size that fits all needs,
so to speak, you can customize the templates to
suit whatever your requirements are. And I'm going to name drop a company that
does just that using this. What they have done use this
over the years, which is square was using this at one point,
and they actually published their moustache templates for
their sdks that they're pushing out. So they were open to taking
community contribs back, to being able to keep those
updated and change them as they needed and take those change
requests in, which is amazing. I've already talked about the
open source, huge community side of things, so again,
please contribute back if you can. Going to keep moving the
generator, the CLI local, CLi aas,
a lot of options. Now, some of these will be very specific
to different language types. Potentially it
just varies depending which language you're outputting.
What I initially did sort of
building out my mvp of SDK generations,
if you will. Originally, when I first started using this,
was building out configuration, yaml configuration,
or JSON configurations for each different language type, and then ingesting
that as part of like a bash script, just to push out a whole bunch
of sdks really quickly in the early days.
So essentially I would load in a, have different
language configs sitting inside a folder,
would run a bash script which would check the folder for the different language configuration
types, and then it would output each of those languages using
that consumption, it would output the SDK generation and you would
get something, or essentially something very similar to that.
This is all on my GitHub too, if you want to have a look.
There's actually a better way to be able to set this
up and have it run automatically in a more automated
way, which is what we're here to talk about today.
But also you can do what I like to call a
360 observability approach to this as well. But we're going to
get into that. So essentially as a containerized
service, this is where things get a little bit more interesting, because you can do
a whole bunch of different automations to help speed this up and
make this a lot quicker. Plus add in some observability to be
able to watch variety of different aspects to
the overall flow. Let me show you what I mean. So we start
with an API, building out a basic
API spec and deploying like a very fundamental API,
maybe powered by a lambda
and a bit of a dynamodb in there. There's some really good examples,
actually. The pet store, if you haven't already got an API, if you want to
try this at home and you haven't already got an API, look for the pet
store demo app to be able to deploy
that and use that open API spec.
Once you generate, have that API running and have that spec
available, you can take that SDK straight out
and load against the containerized open app
service. And then like, so there's
animations output an SDK for a different language type,
which you can then use to run inside something like a lambda
to be able to test the different functions in the SDK.
Now testing the sdks, I can't even stress enough
how critical that is. And this was based on experience
from sdks that I've run in the past, where user feedback will be,
we're not using it because it's using too much resource,
or there's this particular library in it. This is where
testing the actual output at SDK will
help you understand how your end users
are going to use it, and then also the performance they're going to get
when they do use it, which is really critical, again, to making sure
you've got that robust API service.
But this is where distributed tracing can
help, because we're actually able to monitor a whole bunch
of different aspects from this entire flow really, really easy
and really, really quickly. And so for those that aren't familiar
with distributed tracing,
is, if you think about just what we were looking at on that previous
screen, cloud native applications are made up from all these different sort
of microservices these days, and quite
often across region, across different region types,
you'll have a multiple of, not only have a multiple of different services,
but have a multiple of different service versions across multiple
different regions. Things can get rather confusing as to
where everything is, where everything's sitting, and in particular if errors
start to occur in that particular platform. So one
of the more common methods to be able to start to map this through is
distributed tracing as part of the Open Telemetry Foundation's
sort of standardized approach to monitoring, observing and
doing distributed tracing. This is very industry standard
method that's currently being adopted industry wide
to monitor and observe different aspects to internal
microservice infrastructure and in particular deployed
application infrastructure so if we take distributed tracing,
for example, how this can help is being able to make sense from
that multitude of microservice deployments
across multiple or all those different regions helps keeps
things all nice and organized for errors.
In particular, being able to make sense of that entire
end to end flow is really handy, in particular for
app, not only for APIs, but also SDK generation
services, for example, and also sdks that
have been generated, just how they work and how they can have flow
on effects with a variety of different system types.
Best part is, and for those that are familiar with apms
and agent based observability apps,
and I've had my fair share of those over the years with, dare I say,
monolith applications, making sure that the observability
services are kept running or kept on infrastructure as
part of your network deployment is
sometimes quite harrowing. Actually all the time quite harrowing. He's pulled
so many hair out, so much hair out over the years. But what agentless observability
does is be able to sort of trace and make sense of
those services as you go through the way. I like
to think of this in particular to SDK
generation or sdks as a service AAS I like
to look at it is full circle observability,
because what we're going to do is for each of those three streams
we saw in that flow, we're going to apply observability methodology
to be able to see first of all how the API is performing,
including right down to individual API traced invocations.
So being able to map each part of
a particular API invocation journey
is invaluable to tracing a lot of errors or even refinements
you want to do with the API's performance.
But you can also trace, monitor and observe the
deployed SDK service inside a container. So in ecs
in this example, or the deploying
outputted SDK inside a lambda, to be
able to see again how the SDK is performing when
it's deployed as part of an application. Now, the way I based to do
that back in the CLI days, or when I would just generate it
locally, would be to actually have a
single page app that would invoke every function as
part of the call and then try and watch to see how much
memory I was using locally to be able to figure out if it was
doing what it should be doing in the best possible way.
Ultimately, the sdks I was generating, I didn't want to use
more resources than I needed to as part of the user's
application or integration, because nobody wants to be that person.
Anyway, like I was saying, you can use observability to be
able to monitor the likes of API gateway or
your deployed APIs to this
is. I even have an API called Devjoke.
I'll drop the endpoints for it and the access to it later.
But being able to monitor each call from the API right through
to using end to end tracing or even distributed tracing,
to be able to see the API call coming in, the lambda
being called, and then the database response,
being able to see the amount of memory being used and the
amount of resources each one costs is invaluable.
To be able to determine how my API is
not only performing, but how I can make it better. So I
can use these metrics to be able to identify ways that
I can make the API faster, I can make the response time better.
Maybe there's data inside the return
call that doesn't need to be there or needs to be in
a different format. This will basically help me understand how
my users are using or wanting to consume the APIs more,
but then also how it's actually performing as a whole as well.
And you can get quite granular down into the different aspects
of the invocation. To be able to see the serverless
invocation, to be able to see exactly what's going on and
including the most dreaded in the serverless world,
cold starts. Like how that's affecting the response time
and performance from the API as well. But it doesn't stop
there because you can also do the same thing for
the service that you use to the containerized service,
to be able to generate the sdks to begin
with, which is always great to be able to see. And obviously
this isn't going to be something you do all the time and can be quite
automated as well, because ultimately this should only be run,
or only run when a new API deployment has occurred,
into production or into your final we
don't test in production in your staging environment. That's what I aas trying to say.
This doesn't run need to run all the time. It only needs to run when
a new version of the API is available or changes have been made.
That means the SDK needs to be regenerated,
generated as well. Always remember to don't
test in production. To don't test in production. Never test
in production. You know what I mean? This is where I would change to my
this is fine scene, but this is not fine because friends don't let
friends do that. Anyway. You know what I mean,
what's cool here is you can see all your tasks running as part
of that container. Not only can you see tasks running as part of that containerized
service, but you can start to get really refined
down into the, refined into the metrics that are
being captured as part of the containerized service.
So you can see how much memory it's using or
how much resources the container is using, but also if
there's any errors occurring with the generation,
it was sometimes something that I would encounter where particular
part of, or a particular language request generation request
would get stuck on a particular part of this
spec. It was generating the sdks
from AAS part of the output. Actually.
Handy tip one of the most handiest things I think I ever learned is
Python was the most sort of strict
languages as far as usability went with the sdks,
I was generating usually, and don't quote me on this
one, usually when I was using this to
generate a lot of sdks at scale like 40, 50 at a time,
40, 50, different ones, different languages, different products at a time.
The Python ones in each product API product category
were the ones that I would get working first, and generally, once they were
happy, most of the other, usually Touchwood,
most of the other languages would then be able to generate out fairly
quickly and easily. But running that SDK test at the
end of the process to understand what the sdks
were doing and to make sure that they were working, was probably
the most critical final step before that final release stage.
Now, this is something I learned the hard way,
because one time, this one time I actually deployed sdks
without testing them fully, which I very quickly learned
you do not do. Mostly because the time
that I did it, I really remember it
was a busy week. It was always a busy week, and I didn't need to
upset all the users. But we were wondering how many people were
actually using the sdks were pushing up to a variety
of different ecosystems, and it turns out a lot of
people, because when I accidentally broke them one time, we got a lot of emails
in to support saying, hey, the SDK is broken.
Anyway, I fixed them very, very quickly, let me tell you.
Anyway, please make sure you test them first. On that
note, that brings us to the SDK testing section,
because you can deploying, also deploy the sdks you
generate out automatically to either a lambda or
containerized environment. So you can use the same monitoring
to be able to test the performance for the app,
the sdks being generated out,
which is critical to be able to determine things like cold starts
or performance issues before they go into real
world production use, always be
thinking of those end users, and in particular not only that,
but how you want to consume them AAS well, and that
you want to know that somebody has done as much
legwork as they can to make sure these sdks run
as well as they can. Super, super critical. And taking steps
like this just helps understand you understand
how they will run and also what
infrastructure they're going to try and run on. Now, usually when I test these,
either in most environments, I'll go for
the default average set up first, and then if there's any particular
clients or people that I know are using a particular platform language,
et cetera, I'll specifically go through just to check those
as well, or put test cases in place so that
I can make sure I can capture as much as I want.
Actually, on that note too, one of the amazing aspects the
community, the open API creating community has
added over the years is automated test cases
as well, which sometimes may not quite be
what the test cases you are looking for,
but they get pretty close as well. So it's quite easy to
either extend the most moustache templates or have a test
suite of scripts available to be able to test
all the functions properly as part of your load test,
your SDK load testing, or as part of your
overall SDK test as well. But again, this is
where distributed tracing can help because it helps bring you
the full picture. So being able to see the full end to end view
of everything that your application or
everything that a demo application would be able to
output or use or consume or generate AAS part
of its runtime anyway,
just some takeaways as we wrap up, because I am where we're running out of
time. But always design APIs for dev consumption
or just ultimately think about that end user.
Be that a developer user, a business user,
or even your end users end users.
Now we're getting better. Remember to rinse,
repeat and refine. Work out what works. Aas, part of your
API SDK generation flows and continually
look at ways to refine the end to end process and
rinse and repeat. And remember to
monitor and trace everything you possibly can, if only
for the aforementioned points where you're building
out these consumables for
people to be able to build out some really cool experiences.
Always remember to keep your end users in mind as much aas you can,
and also where you possible be the end user and understand
the experience from their point of view, particularly when it comes to API design
because it just enables that way more streamlined
sort of experience when it comes to building out amazing experiences
with your platform. Just lastly,
if you're looking to sort of get more
hands on with distributed tracing, observability, or open telemetry,
check out our blog on Lumigo IO blog and have
a look at some of the articles on there. One of the ones. I mean,
there's so many favorites that my name might appear on there a couple of times,
but I've got a whole series
on app and SDK design coming out soon,
so keep an eye out for that one. Plus, there's some Iot ones on there
as well, which I wrote towards the end of last year that are
kind of fun. Did a whole bunch of 3d printing.
Anyway, that's a talk for another day. And finally,
just remember to always please use your tech superpowers for
good. And remember to be excellent to each other.