WEBVTT

00:00.000 --> 00:10.000
All right, so next song is the editing and the audio.

00:10.000 --> 00:11.000
Thanks.

00:11.000 --> 00:16.000
Thank you.

00:16.000 --> 00:18.000
I'd like to see so many of you here.

00:18.000 --> 00:20.000
I didn't expect this amount of attendance here,

00:20.000 --> 00:23.000
but it's good to see so many people interested in a topic like

00:23.000 --> 00:25.000
David Drake, Stephen Aki, I tools.

00:25.000 --> 00:28.000
Let me say a few words about myself.

00:28.000 --> 00:30.000
I am, oops.

00:30.000 --> 00:32.000
This is not working.

00:32.000 --> 00:34.000
Then I am going to use the keyboard.

00:34.000 --> 00:35.000
My name's Eric.

00:35.000 --> 00:37.000
I'm a software engineer at Profilment Tools.

00:37.000 --> 00:40.000
And in my free time, I'm an open source maintainer in the GraphQL space.

00:40.000 --> 00:42.000
I mainly work on GraphQL in Python,

00:42.000 --> 00:46.000
so that includes the libraries like Graphene and Strawberry.

00:46.000 --> 00:50.000
And let me say a few words about Strawberry first.

00:50.000 --> 00:52.000
Strawberry is a GraphQL framework,

00:52.000 --> 00:54.000
which enables you to easily build GraphQL applications in Python.

00:54.000 --> 00:56.000
It was created by Patrick Aminio.

00:56.000 --> 00:59.000
And it follows an implementation first approach,

00:59.000 --> 01:02.000
which is a subset of code first, GraphQL libraries.

01:02.000 --> 01:04.000
And it's basically inspired by data classes,

01:04.000 --> 01:06.000
and it really makes you implement a GraphQL way,

01:06.000 --> 01:09.000
GraphQL API in a very pathonic way.

01:09.000 --> 01:12.000
And Strawberry offers integrations for Django,

01:12.000 --> 01:14.000
Cicral, Cami, Pedantic, and more.

01:14.000 --> 01:16.000
And if you've been in the Python space,

01:16.000 --> 01:19.000
and you see Python, Django, and Cicral,

01:19.000 --> 01:21.000
you probably know where this is headed a bit.

01:21.000 --> 01:23.000
Just our curiosity, who here has used,

01:23.000 --> 01:25.000
or who is using Python actively.

01:25.000 --> 01:27.000
In an API project, that's nice.

01:27.000 --> 01:30.000
And who here has used GraphQL in Python before?

01:30.000 --> 01:31.000
Okay, not so many.

01:31.000 --> 01:35.000
Maybe I can inspire a few of you to give it a try in the future.

01:35.000 --> 01:37.000
But let's get to the topic,

01:37.000 --> 01:39.000
and have a look at today's API development

01:39.000 --> 01:42.000
and how many of you probably develop your APIs.

01:42.000 --> 01:44.000
And that is using an API first approach.

01:44.000 --> 01:48.000
So basically, you create a concept for something

01:48.000 --> 01:50.000
you want to add to your application.

01:50.000 --> 01:52.000
In this case, we have an example,

01:52.000 --> 01:56.000
API over user, and a post, for example, for block application.

01:56.000 --> 01:59.000
And you can see you have a couple of types, a user type,

01:59.000 --> 02:02.000
which has an ID, and the user name, and the list of posts,

02:02.000 --> 02:05.000
as well as a post type, which consists of, of course,

02:05.000 --> 02:09.000
the title, the content, and you can also fetch the author for a post.

02:09.000 --> 02:12.000
And down here, we enable the user,

02:12.000 --> 02:16.000
or enable any API consumer to fetch users from the API.

02:16.000 --> 02:19.000
This case by ID, and it will turn a user.

02:19.000 --> 02:22.000
If you want to start off when doing sort of API first,

02:22.000 --> 02:24.000
you create a contract, you say, this is our API.

02:24.000 --> 02:26.000
So the consumers know how to use it,

02:26.000 --> 02:28.000
and then you start implementing it.

02:28.000 --> 02:31.000
So basically, instead of implementing this API,

02:31.000 --> 02:33.000
it would look something along the way.

02:33.000 --> 02:34.000
It's lines of this.

02:34.000 --> 02:37.000
Very similar, as you can see, you can see the user class.

02:37.000 --> 02:40.000
You can see the post class, and then to resolve the posts of a user.

02:40.000 --> 02:42.000
You add to certain data resolvers.

02:42.000 --> 02:46.000
Like over here, you call the post service to load the post of a user

02:46.000 --> 02:48.000
with the given user ID.

02:48.000 --> 02:50.000
And you do the same for your queries.

02:50.000 --> 02:54.000
So down here, you add a result to get a user by its ID.

02:54.000 --> 02:57.000
And all of this is manual, you have to add it step by step.

02:57.000 --> 03:00.000
And usually, in order to be able to do that,

03:00.000 --> 03:02.000
you need to implement the methods that are called here.

03:02.000 --> 03:06.000
In this case, we have a service layer, including a post service, a user service,

03:06.000 --> 03:13.000
and this service layer, again, needs to access the database below that

03:13.000 --> 03:15.000
to actually fetch the data.

03:16.000 --> 03:20.000
So after declaring all of this, you again have to make another declaration

03:20.000 --> 03:22.000
step and declare some database models.

03:22.000 --> 03:26.000
In this case, I'm using a Django flavor to just declare the models.

03:26.000 --> 03:29.000
And over here, we have the models for a user and post again.

03:29.000 --> 03:31.000
As you can see, they're very similar.

03:31.000 --> 03:36.000
And they, again, describe how the data is mapped to SQL Arcami,

03:36.000 --> 03:39.000
and to SQL SQL database, I'm sorry.

03:39.000 --> 03:45.000
And yeah, if you map the two SQL, it would look something like this.

03:45.000 --> 03:50.000
And if you remember the schema I showed you, it's very similar,

03:50.000 --> 03:52.000
especially in this overview.

03:52.000 --> 03:55.000
And the question I always have when working on applications like these,

03:55.000 --> 03:57.000
where you have a strict layer separation,

03:57.000 --> 04:00.000
doesn't it feel kind of redundant to declare your types two or three times

04:00.000 --> 04:02.000
with minimal differences in the fields?

04:02.000 --> 04:06.000
Okay, I'm not going to argue against clear separation of concerns

04:06.000 --> 04:08.000
and applications that's an important pattern,

04:08.000 --> 04:10.000
and it has its sense.

04:10.000 --> 04:12.000
But in very quite heavy applications,

04:12.000 --> 04:16.000
just pulling your username through with the same type through all of your layers

04:16.000 --> 04:18.000
and your application can sometimes feel exhausting,

04:18.000 --> 04:20.000
and it can take up a lot of your development time.

04:20.000 --> 04:24.000
You could use for other valuable things like actual features.

04:24.000 --> 04:27.000
So I wonder, doesn't it feel redundant to do it a bit?

04:27.000 --> 04:30.000
And let's examine this further a bit at first,

04:30.000 --> 04:35.000
by looking at the control flow of such an application as the one I've shown you.

04:35.000 --> 04:38.000
So right here on the left side we have a sample query,

04:38.000 --> 04:40.000
which just gets the user of the ID one

04:40.000 --> 04:43.000
and touches all of the posts associated to that user.

04:43.000 --> 04:46.000
And this query is usually passed by a GraphQL execution engine,

04:46.000 --> 04:50.000
which then calls the appropriate data resolvers to you have defined in your schema.

04:50.000 --> 04:52.000
So in our case, it was the user resolver.

04:52.000 --> 04:54.000
And then, next the user resolver,

04:54.000 --> 04:58.000
it calls the user service to actually fetch this user

04:58.000 --> 04:59.000
from the database.

04:59.000 --> 05:02.000
And then the data flow goes on to the object relational method,

05:02.000 --> 05:04.000
the Django models, I've just shown you,

05:04.000 --> 05:07.000
to generate a SQL query to actually fetch the user from the database.

05:07.000 --> 05:11.000
So in this case, we can see select ID username from users is one.

05:11.000 --> 05:16.000
So next up, we need to fetch the posts connected to the user over here.

05:16.000 --> 05:19.000
So once again, after the user is resolved,

05:19.000 --> 05:22.000
neglected execution engine goes ahead and resolves the posts,

05:22.000 --> 05:23.000
fields of the users.

05:23.000 --> 05:26.000
And again, here the user post resolver is called.

05:26.000 --> 05:29.000
It invokes the post service to get all of the posts from the database.

05:29.000 --> 05:34.000
And again, another SQL query over here is formulated.

05:34.000 --> 05:39.000
So when you build such an application,

05:39.000 --> 05:41.000
basically you need all of your service layers.

05:41.000 --> 05:43.000
You need your database access layer,

05:43.000 --> 05:44.000
and you need your schema layer.

05:44.000 --> 05:46.000
And then you need to glue it together.

05:46.000 --> 05:49.000
Using a lot of glue code, right?

05:49.000 --> 05:52.000
Calling all of the services from each other.

05:52.000 --> 05:56.000
And this is where database revenue APIs come in.

05:56.000 --> 05:59.000
Because the paradigm has just shown you,

05:59.000 --> 06:03.000
basically has a workflow from the left side to the right side.

06:03.000 --> 06:05.000
You start with an API schema,

06:05.000 --> 06:07.000
and you end up at a database schema,

06:07.000 --> 06:11.000
which fits the kind of API you want to provide to your consumers.

06:11.000 --> 06:14.000
And as we've just seen, for many cases,

06:14.000 --> 06:17.000
like the one over here, the database schema already contains

06:17.000 --> 06:20.000
enough information to infer an API schema from it.

06:20.000 --> 06:22.000
Right? We have the database types.

06:22.000 --> 06:25.000
For example, strings, we know primary keys are IDs in our schema.

06:25.000 --> 06:26.000
We know the relationships.

06:26.000 --> 06:28.000
For example, by foreign key relations,

06:28.000 --> 06:31.000
we know which types are connected to each other

06:31.000 --> 06:33.000
in our GraphQL schema.

06:33.000 --> 06:36.000
So basically, in database revenue APIs,

06:36.000 --> 06:39.000
we want to go from this to this,

06:39.000 --> 06:42.000
and actually infer the API schema

06:42.000 --> 06:44.000
for what we have in our database schema.

06:48.000 --> 06:51.000
In this case, for our strawberry-based approach,

06:51.000 --> 06:53.000
we would want to take this Django model.

06:53.000 --> 06:55.000
We formulated for our database schema,

06:55.000 --> 06:59.000
and it somehow generated the GraphQL schema out of it.

06:59.000 --> 07:01.000
And for strawberry Django, it's easy

07:01.000 --> 07:03.000
as replacing the code with this.

07:03.000 --> 07:06.000
So now over here, you can see a lot of things have changed.

07:06.000 --> 07:09.000
I removed all of the fields from the user and post type,

07:09.000 --> 07:12.000
and we changed the annotation up here to a strawberry Django type.

07:12.000 --> 07:15.000
And in that case, it tells strawberry Django

07:15.000 --> 07:18.000
to actually take all of the fields from the post model

07:18.000 --> 07:20.000
and put them into the GraphQL schema.

07:20.000 --> 07:23.000
There are some static methods, for example,

07:23.000 --> 07:26.000
for the foreign keys, for the chart fields, and for the text fields,

07:26.000 --> 07:28.000
which are mapped to appropriate GraphQL scalers

07:28.000 --> 07:30.000
in the GraphQL schema.

07:30.000 --> 07:32.000
And the most magical thing about this

07:32.000 --> 07:34.000
is that you don't have to care about data

07:34.000 --> 07:35.000
resolving any more either.

07:35.000 --> 07:37.000
Because now you can just plug in

07:37.000 --> 07:40.000
that strawberry Django field into your query type,

07:40.000 --> 07:42.000
and everything we have done before

07:42.000 --> 07:44.000
to fetch a user by its ID or to fetch a list of users

07:44.000 --> 07:48.000
is automatically handled for you by the framework.

07:48.000 --> 07:51.000
I'll show you that in a second.

07:51.000 --> 07:53.000
Basically, having a look at our control floor

07:53.000 --> 07:57.000
from before again, all of this glue code you had to write before.

07:57.000 --> 07:59.000
You can remove it with strawberry Django.

07:59.000 --> 08:02.000
You don't need a user service or a specific user

08:02.000 --> 08:03.000
resolver for your example anymore.

08:03.000 --> 08:06.000
It will be handled for you by the framework.

08:06.000 --> 08:09.000
Instead, you plug it in, and you get some new features

08:09.000 --> 08:11.000
like query optimizations.

08:11.000 --> 08:14.000
So if you look at the query before,

08:14.000 --> 08:17.000
you have two separate queries which are called

08:17.000 --> 08:18.000
and that is kind of inefficient.

08:18.000 --> 08:20.000
You want to use or leverage the query planner

08:20.000 --> 08:23.000
that is provided to you by the database

08:23.000 --> 08:24.000
as much as possible.

08:24.000 --> 08:26.000
Like you cannot write a more efficient query

08:26.000 --> 08:27.000
than any of your business logic,

08:27.000 --> 08:30.000
then it's already present in any database you're using.

08:30.000 --> 08:33.000
And frameworks like strawberry Django

08:33.000 --> 08:35.000
are able to read the GraphQL query

08:35.000 --> 08:38.000
to analyze what's field you request it

08:38.000 --> 08:41.000
which relationships need to be joined onto the query

08:41.000 --> 08:44.000
and generate a corresponding SQL query

08:44.000 --> 08:47.000
out of it to optimize the way you fetch your data.

08:47.000 --> 08:49.000
And it's all automatically done in the background

08:49.000 --> 08:52.000
you don't have to do anything for it.

08:52.000 --> 08:54.000
The next feature you just get for free

08:54.000 --> 08:56.000
is a pagination interface.

08:56.000 --> 08:59.000
Basically, if you know about cursor-based pagination,

08:59.000 --> 09:01.000
it's all implemented there.

09:01.000 --> 09:04.000
You could also add other pagination styles and

09:04.000 --> 09:07.000
flavors and have that automatically generated for you.

09:07.000 --> 09:10.000
Another nice feature is automated filtering

09:10.000 --> 09:13.000
because at least I also have a lot of struggles

09:13.000 --> 09:16.000
with adding a lot of filters to my API.

09:16.000 --> 09:18.000
Because it's kind of annoying.

09:18.000 --> 09:19.000
It's very simple.

09:19.000 --> 09:22.000
You have to edit in all of the layers in your usual code base

09:22.000 --> 09:25.000
and with sorry Django, all the filters that are available

09:25.000 --> 09:28.000
on your SQL model are automatically available in your API

09:28.000 --> 09:29.000
if you choose to do so.

09:29.000 --> 09:33.000
For example here, I can filter all use by a user name

09:33.000 --> 09:37.000
that starts with Eric and then that will work.

09:37.000 --> 09:40.000
One of the nice things about strawberry Django

09:40.000 --> 09:44.000
is that you can automatically create track mutations.

09:44.000 --> 09:47.000
Basically create update, delete mutations,

09:47.000 --> 09:51.000
which insert the entities based on the database schema.

09:51.000 --> 09:55.000
So with this, you have already covered a large part

09:55.000 --> 09:57.000
of basic application functionality.

09:57.000 --> 10:00.000
Like reading data, reading lists of data

10:00.000 --> 10:02.000
and modifying the data.

10:02.000 --> 10:04.000
But many applications have custom requirements.

10:04.000 --> 10:07.000
You don't want any type to have any filter available

10:07.000 --> 10:11.000
or maybe any field in your database should be accessible.

10:11.000 --> 10:13.000
For example, a password hash, if you start in your database

10:13.000 --> 10:16.000
for some reason, shouldn't really be accessed accessible

10:16.000 --> 10:17.000
in the API.

10:17.000 --> 10:20.000
That is where customization plays an important role.

10:20.000 --> 10:24.000
And shortly, Django, it's really easy to do that.

10:24.000 --> 10:27.000
Over here, you can see our post type again.

10:27.000 --> 10:29.000
And I've added the fields back.

10:29.000 --> 10:33.000
However, I haven't added the back exactly as in the example

10:33.000 --> 10:34.000
in the beginning.

10:34.000 --> 10:36.000
You can see here, I added the title fields.

10:36.000 --> 10:39.000
But I annotated the type of the title fields as auto.

10:39.000 --> 10:41.000
And auto just tells the framework

10:41.000 --> 10:45.000
to resolve the type based on the schema type in the database.

10:45.000 --> 10:49.000
I wanted to modify the content field to a type called Markdown

10:49.000 --> 10:52.000
just to signify that this requires some additional

10:52.000 --> 10:53.000
parsing.

10:53.000 --> 10:55.000
And I can do it as simple as changing the type here.

10:55.000 --> 10:57.000
And the framework will automatically

10:57.000 --> 11:00.000
still resolve it back to the database type.

11:00.000 --> 11:03.000
Another thing I can do is use other nice features of strawberry

11:03.000 --> 11:05.000
like automatic handling of permissions

11:05.000 --> 11:07.000
and add them to the fields in the database.

11:07.000 --> 11:09.000
And it will be resolved for you.

11:09.000 --> 11:10.000
So it's really fluent.

11:10.000 --> 11:14.000
The kind of customization you can do from a purely database

11:14.000 --> 11:18.000
oriented type to some type with a little bit of business logic.

11:18.000 --> 11:21.000
You choose how much you want to add.

11:21.000 --> 11:24.000
And the next important part after customization

11:24.000 --> 11:26.000
is extension of your API.

11:26.000 --> 11:29.000
Maybe sometimes the database type is not enough.

11:29.000 --> 11:31.000
You need some custom logic on top of it.

11:31.000 --> 11:34.000
That's why accessibility is very important to do easily

11:34.000 --> 11:35.000
in such frameworks.

11:35.000 --> 11:39.000
So this example, you can see that I added a resolver for a post

11:39.000 --> 11:41.000
caption to all the post five.

11:41.000 --> 11:44.000
And as you can see, you can just use the data provided

11:44.000 --> 11:46.000
in the database model inside of these resolvers.

11:46.000 --> 11:49.000
For example, here the caption's just the title with the current date.

11:49.000 --> 11:52.000
And I can access all of the database fields in these resolvers

11:52.000 --> 11:55.000
and do not have to worry about any missing data,

11:55.000 --> 11:57.000
not being present.

11:58.000 --> 12:01.000
So far so good.

12:01.000 --> 12:05.000
We've now talked about an extensible approach

12:05.000 --> 12:09.000
to generate your objective graphical schema from a database schema.

12:09.000 --> 12:10.000
Right?

12:10.000 --> 12:12.000
You are starting off with a strawberry code base.

12:12.000 --> 12:14.000
You have your web server hooked up.

12:14.000 --> 12:16.000
And you have all the configuration already present.

12:16.000 --> 12:18.000
And then you plug in strawberry Django.

12:18.000 --> 12:22.000
And the Django or M to actually infer any models.

12:22.000 --> 12:26.000
And infer this database schema from those models.

12:26.000 --> 12:30.000
And then up cases where you don't actually want that.

12:30.000 --> 12:31.000
Or you don't need that.

12:31.000 --> 12:32.000
You just have your database.

12:32.000 --> 12:35.000
And you want to get a graphical schema that actually enables you

12:35.000 --> 12:37.000
to do what you want.

12:37.000 --> 12:41.000
And this case is actually very important because in many,

12:41.000 --> 12:43.000
there's a lot of use cases nowadays.

12:43.000 --> 12:45.000
For example, grab your APIs.

12:45.000 --> 12:48.000
I use an LLMs or AI use cases in general.

12:48.000 --> 12:50.000
And you just want access to the data,

12:50.000 --> 12:52.000
but not to the raw database.

12:53.000 --> 12:57.000
And this is where tools like Post Graphile come in very handy.

12:57.000 --> 13:01.000
Because they enable you to create a GraphQL schema just

13:01.000 --> 13:04.000
from a Postgres database without any additional framework

13:04.000 --> 13:05.000
or wiring.

13:05.000 --> 13:06.000
You have to do around it.

13:06.000 --> 13:07.000
You just install it.

13:07.000 --> 13:08.000
And it works.

13:08.000 --> 13:12.000
But still it's as extensible as the approach I've shown you before.

13:12.000 --> 13:18.000
And what Post Graphile does is it reads the Postgres schema

13:18.000 --> 13:21.000
that is stored in the database to automatically generate the API.

13:21.000 --> 13:23.000
So you don't even have to define any models.

13:23.000 --> 13:25.000
It's automatically read from the schema.

13:25.000 --> 13:28.000
And similar to Strawberry Django,

13:28.000 --> 13:31.000
Quad mutations, and all of the nice logic and the nice extras

13:31.000 --> 13:34.000
like filtering, pagination are added automatically for you.

13:34.000 --> 13:39.000
And you can extend it even further using a right variety of plugins.

13:39.000 --> 13:42.000
I want to give you a little comparison.

13:42.000 --> 13:44.000
It's going to be a bit harder to read,

13:44.000 --> 13:48.000
but between Strawberry Django and Post Graphile.

13:48.000 --> 13:52.000
So on the one hand, in Strawberry Django, you see I added some documentation

13:52.000 --> 13:53.000
to the Post type.

13:53.000 --> 13:57.000
And I also added some other information.

13:57.000 --> 13:59.000
For example, I might have excluded a field here.

13:59.000 --> 14:03.000
And all of this is handled via smart text in the database in Post Graphile.

14:03.000 --> 14:08.000
So up here, for example, you can see the first tag is a comment

14:08.000 --> 14:10.000
which I added on the Posts table.

14:10.000 --> 14:13.000
And basically this will also lead to the Posts table being documented

14:13.000 --> 14:15.000
in the GraphQL schema.

14:15.000 --> 14:18.000
When I want to exclude fields, again, it's a smart tag.

14:18.000 --> 14:20.000
It's the omit tag.

14:20.000 --> 14:24.000
And here, I am extending a certain private field from the post type

14:24.000 --> 14:27.000
by omitting it for reading from the API.

14:27.000 --> 14:30.000
And you can do the same for filters, pagination,

14:30.000 --> 14:33.000
or actually relationships, and maybe even whole types in your database,

14:33.000 --> 14:36.000
schema that you don't want to expose in the API.

14:36.000 --> 14:39.000
And also, this is logic is possible to be implemented.

14:39.000 --> 14:42.000
Like down here, the caption of the post,

14:42.000 --> 14:44.000
is just represented via a SQL.

14:44.000 --> 14:47.000
We are post based function, which again, we solve status.

14:47.000 --> 14:51.000
And you can automatically plug that into your schema.

14:51.000 --> 14:56.000
So let's compare the two approaches on a basic level.

14:56.000 --> 14:58.000
Both are very extensible.

14:58.000 --> 15:01.000
You start with a set of features that every application needs,

15:01.000 --> 15:05.000
and you are good to go in minutes.

15:05.000 --> 15:09.000
But the main difference is that strawberry agenda really requires you

15:09.000 --> 15:12.000
to have your strawberry up around it,

15:12.000 --> 15:15.000
and your Python ecosystem of tools to get it going.

15:15.000 --> 15:18.000
Our post graph is up and running right away.

15:18.000 --> 15:22.000
You can, however, extend it and extend it with no JS code

15:22.000 --> 15:25.000
to actually add more business logic, add more custom features,

15:25.000 --> 15:29.000
and extend the schema, but it just works right out of the box.

15:29.000 --> 15:32.000
Another big difference is that post graph

15:32.000 --> 15:35.000
are really focused on having business logic in the database,

15:35.000 --> 15:38.000
utilizing as much of the database as possible,

15:38.000 --> 15:42.000
what strawberry Django is really focused on the features

15:42.000 --> 15:45.000
that are present within an ORM.

15:45.000 --> 15:49.000
So basically the database schema and the relationships you define.

15:49.000 --> 15:53.000
And another difference is that post graph is just made for post graphs,

15:53.000 --> 15:57.000
and strawberry Django supports all SQL implementations,

15:57.000 --> 16:00.000
which are supported by Django or RAM.

16:00.000 --> 16:03.000
But if you ask me a nowadays world,

16:03.000 --> 16:06.000
it's probably always best to use post graphs for most use cases,

16:06.000 --> 16:10.000
and it's not meant much of a mis to not have support,

16:10.000 --> 16:14.000
for example, my SQL in those applications.

16:14.000 --> 16:17.000
So let's talk about a few common pitfalls.

16:17.000 --> 16:20.000
I get a lot of questions about migrations.

16:20.000 --> 16:24.000
For example, many people are concerned

16:24.000 --> 16:27.000
when coupling your database a bit tighter to your schema

16:27.000 --> 16:29.000
on how to do migrations.

16:29.000 --> 16:32.000
And actually my answer to that is pretty straightforward

16:32.000 --> 16:34.000
when you're doing migrations in an application,

16:34.000 --> 16:36.000
especially in a distributed system.

16:36.000 --> 16:39.000
You also have to worry about not breaking things

16:39.000 --> 16:41.000
based on the consumers of that database.

16:41.000 --> 16:44.000
You have to be very careful if you're removing fields,

16:44.000 --> 16:47.000
changing field types, and you have to do that incrementally.

16:47.000 --> 16:49.000
For example, if you change the name of a field,

16:49.000 --> 16:51.000
you have to keep the old name there.

16:51.000 --> 16:54.000
And with tools like strawberry Django and post graph file,

16:54.000 --> 16:59.000
it's very easy to add smart tags or custom logic to change field names

16:59.000 --> 17:01.000
and map to the old fields first,

17:01.000 --> 17:03.000
and after the migrations completed,

17:03.000 --> 17:06.000
you have to make an API breaking change.

17:06.000 --> 17:10.000
Because while the GraphQL schema is met to the database schema,

17:10.000 --> 17:12.000
there are ways to customize it,

17:12.000 --> 17:16.000
and there are ways to actually direct the data to the point

17:16.000 --> 17:19.000
where you want it, and to use the database columns

17:19.000 --> 17:22.000
that you're actually interested in.

17:22.000 --> 17:27.000
This was mostly focused on GraphQL for now.

17:27.000 --> 17:30.000
Since I'm working GraphQL, I'm a bit biased,

17:30.000 --> 17:33.000
but I'm probably telling you the best way to do this is via GraphQL,

17:33.000 --> 17:37.000
but there's great tools out there to do this in REST APIs as well.

17:37.000 --> 17:42.000
First example is Postgres, which enables you to build a REST API

17:42.000 --> 17:45.000
from your Postgres databases.

17:45.000 --> 17:47.000
For example, the Python ecosystem,

17:47.000 --> 17:51.000
there's a two like SQL model, which will also decrease the amount of workload you have

17:51.000 --> 17:55.000
or the amount of layers you have to go through to map a database model

17:55.000 --> 17:58.000
to an API model that is actually validated.

17:58.000 --> 18:02.000
So, some of the database-driven APIs

18:02.000 --> 18:05.000
derive an API schema from the database schema,

18:05.000 --> 18:11.000
and they generate API types from the native types in your database.

18:11.000 --> 18:15.000
And tools like Postgres file can leverage native database features

18:15.000 --> 18:19.000
to use your technology as efficiently as possible,

18:19.000 --> 18:24.000
without having to duplicate any types throughout the layers of your applications.

18:24.000 --> 18:27.000
And by doing that, you are able to iterate rapidly.

18:28.000 --> 18:31.000
I told you, you just have to start the tool and the API is going,

18:31.000 --> 18:33.000
and then you can start with customization.

18:33.000 --> 18:35.000
Usually, when you're developing an application,

18:35.000 --> 18:37.000
you're adding a new feature, for example, a post feature,

18:37.000 --> 18:40.000
you first need to edit everywhere, you code it,

18:40.000 --> 18:44.000
and then, at some point, you can integrate it with Post GraphQL,

18:44.000 --> 18:49.000
or Strawberry Django, everything is there immediately.

18:49.000 --> 18:52.000
So, when we're talking about database-driven API tools,

18:52.000 --> 18:56.000
we should also talk about when not to use database-driven API tools.

18:57.000 --> 18:59.000
And for me, the answer is,

18:59.000 --> 19:02.000
it really depends on the kind of application you're building.

19:02.000 --> 19:05.000
And I really see it as a spectrum from pure-cut applications

19:05.000 --> 19:09.000
on the one hand, which just have data you put into the database,

19:09.000 --> 19:13.000
that's created, update, and delete mutations to modify that data,

19:13.000 --> 19:15.000
and on the other hand, there's very behavior-centric apps,

19:15.000 --> 19:18.000
very domain-driven applications with lots of business logic

19:18.000 --> 19:20.000
custom code inside.

19:20.000 --> 19:23.000
And I think for pure-cut applications, it's obvious.

19:24.000 --> 19:26.000
Try it out, see if it works for you,

19:26.000 --> 19:28.000
and it can save you a lot of time,

19:28.000 --> 19:33.000
and bring you a lot of features, make your API greater than it ever used to be.

19:33.000 --> 19:38.000
However, I don't think it only is only a good choice for pure-cut applications.

19:38.000 --> 19:43.000
I think the separation point is somewhere around here,

19:43.000 --> 19:46.000
because from my experience, even very behavior-centric applications,

19:46.000 --> 19:50.000
with a lot of domain logic, contain a large part that is purely cut

19:50.000 --> 19:52.000
for many types that are in the application.

19:52.000 --> 19:55.000
And for this part of the application, you can still benefit largely

19:55.000 --> 19:58.000
from using a database-driven API tool.

19:58.000 --> 20:03.000
So, why should you use database-driven API tools?

20:03.000 --> 20:06.000
Basically, you can utilize your technologies effectively,

20:06.000 --> 20:10.000
save a lot of time, and get going with minimal boilerplate or blue code

20:10.000 --> 20:12.000
in your application.

20:12.000 --> 20:15.000
Additionally, you can make sure your database schema

20:15.000 --> 20:18.000
is at all times consistent to your API schema,

20:18.000 --> 20:20.000
where you want it to be consistent,

20:20.000 --> 20:23.000
and you don't have any duplicate types you need to work on.

20:23.000 --> 20:26.000
And this, all in all, enables you to innovate rapidly,

20:26.000 --> 20:30.000
and build nice tools faster and easier than ever before.

20:30.000 --> 20:31.000
Thank you.

20:31.000 --> 20:33.000
Over here, you find the QR code to my LinkedIn,

20:33.000 --> 20:35.000
feel free to contact me with any questions,

20:35.000 --> 20:38.000
and here you can find two links to the docs of the tools I presented.

20:39.000 --> 20:48.000
Any questions?

20:48.000 --> 20:50.000
Yes?

20:50.000 --> 20:53.000
There are any, or, are you aware of any kind of authorization

20:53.000 --> 20:56.000
or access to the management?

20:56.000 --> 21:01.000
So, I haven't gone too deep into this because the lack of time,

21:01.000 --> 21:05.000
but I'm post graph, how you can do authorization also within Postgres.

21:05.000 --> 21:06.000
There's a good feature.

21:06.000 --> 21:08.000
I'll ask Benji back there for more details.

21:08.000 --> 21:10.000
He's a maintainer of post graph files.

21:10.000 --> 21:13.000
And post strawberry, for strawberry, Django and strawberry,

21:13.000 --> 21:15.000
and all those database tools,

21:15.000 --> 21:19.000
it's very easy to just plug it into the existing strawberry provision system

21:19.000 --> 21:21.000
that we have going.

21:21.000 --> 21:22.000
Yes?

21:22.000 --> 21:23.000
Yes?

21:23.000 --> 21:25.000
You talk about migrations.

21:25.000 --> 21:27.000
What do you know about provision?

21:27.000 --> 21:28.000
Is it possible?

21:28.000 --> 21:29.000
How is it used?

21:29.000 --> 21:30.000
Okay.

21:30.000 --> 21:33.000
So, since this talk is more focused on GraphQL,

21:33.000 --> 21:37.000
the general recommendation in GraphQL is to not version your entire schema,

21:37.000 --> 21:42.000
but to keep your schema evolving and back what's compatible is much as possible over time.

21:42.000 --> 21:45.000
There's no real versioning strategy that I have in mind,

21:45.000 --> 21:48.000
like right from the back, it would depend on the specific use case probably.

21:48.000 --> 21:52.000
General recommendation I can give is to version by field,

21:52.000 --> 21:55.000
so basically at a new type, next to your old type,

21:55.000 --> 21:58.000
if you want to make breaking changes to the API schema.

21:58.000 --> 21:59.000
Yes?

22:00.000 --> 22:02.000
Yeah?

22:02.000 --> 22:05.000
Are you going on a little bit to the opposite direction of what GraphQL,

22:05.000 --> 22:08.000
or is you want to do an extra from the database?

22:08.000 --> 22:11.000
And I want to try to kind of attempt the end,

22:11.000 --> 22:14.000
I always end up having to sort of choose to give a dive version

22:14.000 --> 22:16.000
and then I can use the tools anymore,

22:16.000 --> 22:18.000
and I have them in interest.

22:18.000 --> 22:20.000
I like the question,

22:20.000 --> 22:23.000
because when many people first discover GraphQL,

22:23.000 --> 22:25.000
they think, oh, nice, it's a big database.

22:25.000 --> 22:28.000
I can use to access all of my data without limits.

22:28.000 --> 22:30.000
And this is not what GraphQL should be.

22:30.000 --> 22:33.000
These tools might enable you to do that.

22:33.000 --> 22:35.000
What I maybe didn't mention here enough

22:35.000 --> 22:38.000
is that you should still stick to certain best practices,

22:38.000 --> 22:42.000
do not expose everything, do not expose every relationship

22:42.000 --> 22:44.000
and every field in your database schema,

22:44.000 --> 22:47.000
expose the data that is necessary to deliver your application

22:47.000 --> 22:49.000
the way you want it to be delivered.

22:49.000 --> 22:52.000
And that is the big advantage of these tools.

22:52.000 --> 22:54.000
You are able to build a database,

22:54.000 --> 22:56.000
like a database access tool,

22:56.000 --> 22:58.000
out of them, because they are so powerful,

22:58.000 --> 23:00.000
but with great power comes great responsibility,

23:00.000 --> 23:03.000
and after all, at some point,

23:03.000 --> 23:05.000
you really need to,

23:05.000 --> 23:06.000
if you stick to best practices,

23:06.000 --> 23:08.000
you will not run into these risks.

23:08.000 --> 23:12.000
Any more questions?

23:12.000 --> 23:14.000
Then, thanks everyone.

23:14.000 --> 23:16.000
There's some stickers.

23:16.000 --> 23:18.000
Thank you.

23:18.000 --> 23:20.000
Thank you.

23:20.000 --> 23:22.000
Thank you.

23:22.000 --> 23:24.000
Thank you.

