►
Description
The issue that we want to implement: https://gitlab.com/gitlab-org/gitlab/-/issues/342437.
The GitLab GraphQL style guide: https://docs.gitlab.com/ee/development/api_graphql_styleguide.html.
The GraphQL gem docs: https://graphql-ruby.org/.
The GraphQL explorer GitLab.com: https://gitlab.com/-/graphql-explorer
A
Hello,
everyone
I'm
David
from
the
package
team
and
in
today's
video
we
are
going
to
go
through
a
pair
programming
session
about
graphql
with
me.
Today
we
have
Dima
and
Raul
so
hello
and
we
are
going
to
tackle
this
issue,
which
is
having
a
graphql
mutation
to
delete
packages
in
bulk,
so
delete
multiple
packages
in
one
request.
A
A
A
Okay,
so
graphql
I,
don't
know
which
level
of
your
graphql
knowledge
is
so
I
guess
I
will
be
trying
to
summarize
some
Concepts.
If
you
have
any
questions,
just
stop
me
and-
and
we
can
go
into
details-
I'm,
not
sure
how
much
of
the
implementation
we
would
get
done,
but
we'll
see
at
the
end,
I
will
finish
the
implementation
today
and
I
will
open,
NMR
and
and
yeah
since
you're.
Working
on
this
with
me,
you
will
be
credited
on
on
on
that
MR2.
B
A
A
That's
the
two
type
of
requests,
better
set,
two
types
of
queries
that
you
can
make,
so
the
rate
requests
are
called
queries
so
short
and
simple,
the
other
ones,
the
the
ones
that
do
some
rights.
They
are
called
mutations,
and
here
we
are
going
to
delete
packages,
so
we
are
going
to
introduce
a
new
mutation
on
graphql.
A
B
Github.Com,
so
this
is.com,
we
have
access
to
this
graphql
Explorer.
A
And
you
can
actually
browse
the
schema.
It's
here.
A
Queries
are
quite
simple:
you
you
really
navigate
through
objects.
So
let's
say
you
can
query
the
project
which
is
here.
This
will
return
a
project
type
and
if
you
open
the
project
tab,
you
have
then
fields
and
I'm
I'm
taking
a
field
randomly
right,
but
we
are
going
to
read
packages.
B
A
Yeah,
if
we
open
the
connection,
we
have
some
fields
that
are
used
by
the
graphql
clients.
The
most
interesting
one
is
the
nodes
that
contains
the
the
array
of
package.
A
So
how
these
look
like
on
the
query,
so
you
first
of
all
right
which
type
of
query
you
want.
So
here
we
want
to
query.
A
A
So
the
query,
then
we
have
the
project.
A
A
Okay
and
then
we
open
it's
like
it's
like
opening
the
the
project
value
that
is
written,
and
here
we
are
on
the
project
value,
so
we
can
ask
for
the
packages
which
will
return
a
connection.
We
open
that
connection.
We
are
interested
in
the
nodes,
we
open
the
nodes,
and
here
it's
the
fields
of
the
of
the
package,
so.
B
We
just
list
whatever
field
we
we
want.
Let's
execute.
A
This,
and
so
we
we
have
two
packages
on
that
that
project.
That's
a
query:
the
mutation,
it's
the
mutation
is
exactly
the
same.
It's
just
that
mutations
are
more
complex
inputs
because
usually
limitations
can
be.
For
example,
you
can
update
an
object,
so
you
will
need
to
pass
as
an
input
all
the
updated
fields
that
you
all
the
fields
that
you
want
to
update.
So
it's
it's
similar
with
more.
A
Okay,
no
questions
so
far.
B
A
B
On
on
gitlab,
so
it's
it's
handy.
A
To
have
this
page
on
the
side?
Okay,
so
we
are
going
to
build
the
the
mutation
I'm
going
to
take
a
shortcut
here,
because
I
know
that
we
do
have
the
mutation
to
delete
multiple
package
files,
so
I'm
going
to.
B
Have
a
look
at
that,
so
it's
graphql
packages
destroy
or
files.
A
You
can
basically
have
it
where
you
want,
but
we
we
do
have
some
code
organization
at
GitHub.
Otherwise
that
would
be
the
wide
west
I
guess.
So
we
do
have
a
namespace
for
mutations.
Then
it's
pretty
much
splitted
into
functional
area.
So
we
do
have
one
namespace
for
packages
and
then
we
have
all
the
you.
A
A
A
And
then
the
most
important
function
is
the
result,
so
the
the
result
function
is
basically
taking
the
inputs
of
the
mutation
and
just
execute
the
mutation
and
returning
returning
either
a
message
or
an
ntra
or
errors
or
whatever.
The
the
inputs
of
the
of
the
result.
Function
are
exactly
the
ones
that
are
stated
as
Arguments
for.
A
A
We
can
keep
that
and
get
inspired,
no
copy.
We
don't
copy
code
code.
Duplication
is
bad.
We
just
get
inspired
by
this
class
and
and
create
one
that
does
pretty
much
the
same
thing,
but
it
works
on
packages.
A
Yeah,
so
this
one
that's
a
custom
helper
on
GitHub,
so
we
do
have
a
lot
of
queries
and
mutations
that
use
a
project
path
as
a
as
an
argument,
and
so
this
this
thing
provides
it's
the
defined
project
based
on
on
Project
path,
is
to
find
a
Project
based
on
this.
The
input
and
that
will
get
executed
by
this
line.
Motorola
is
fine.
A
It's
yeah!
It's
it's
not
super
clear
because
it's
like
helpers
using
helpers,
and
so
it's
not
super
clear,
but
this
thing
will
call
I
think
it's
called
it
expects
to
have
a
function
called
find
object
and
it
will
actually
find
the
object
and
check
this
permission
on
the
find
object
and
just
fail.
If,
if
the
user
doesn't
have
the
the
object,
we
can
check
on
the
I
think
we
do
have
that
on
the
destroy
package,
five,
so
same
mutation,
but
this
one
is
just
for
one
package
file.
A
So
there
is
no
project
path,
so
we
don't.
We
don't
include
but
find
the
project
path.
Instead,
what
we
do
is
that
we
find
the
package
file
directly
by
its
ID,
and
you
see
this
is
the
the
function
that
this
method
expects
to
be
defined,
assign
object
and
it's
actually
using
the.
B
Same
input,
the.
A
Same
parameters,
so
here
since
we
didn't
use
the
project
helper,
we
Define
defined
object
directly,
but
here
since
it's
the
project
path,
we
can
use
the
finds
project.
I
guess
we
can
open
it.
Let's
see
what
what
this
has
but
I
guess.
It's
almost
just
find
object.
You
see
yeah,
just
fine.
It's
just
a
way
to
avoid
everyone
to
Define
this
function
on
their
mutation
yeah,
but
yeah.
There
is
something
to
to
know
it's
that
the
authorized
fine.
Well,
actually,
you
can
always
check.
B
For
it
authorize
find.
A
You
can
always
search
for
the
function.
Oh.
B
A
Yeah,
so
it's
actually
me
that
doesn't
know
how
to
write
so
it's
yeah
as
I
said
it's
finding
the
object.
You
see
this.
The
call
here
on
the
find
object,
method,
another
object
that
has
been
patched.
We
will
call
the
authorized
which
is
just
below,
and
it's
it's
actually,
oh,
that
okay
I,
like
those
constructions
where
you
your
functions,
that
are
only
one
single
line
but
okay.
Why
not?
So
it
will
just
check
if
we
do
have
the
authorization
on
that
object.
A
The
current
user
is
something
that
you
more
or
less
always
have
on
all
mutations.
Query
resolvers
everywhere.
A
A
A
Is
that
clear
or
yeah,
okay,
yep
yeah?
We
can
keep
this
one,
so
we
are
going
to
have
a
destroy.
A
Is
naming
like
I'd
like
to
put
like
destroy
I,
don't
know
packages.rv
yeah?
Why
not?
But
we
do
have
packages
twice
right:
yep,
yep
I'm,
as
I
said
several
times.
I'm
a
simple
man
like
duplicating
packages
doesn't
bring
value
so
yeah.
Well,
we
we
can
go
with
bulk,
destroy
I,
guess
yeah.
That
should
be
quite
explicit.
If
you
have
some
ideas,
don't
hesitate
to
to
give
me
names
yeah.
Well,
let's
go
with
this
and
we'll
see
so
yeah
I'm,
super
lazy,
so
I
will
start.
A
It's
destroyed
packages,
we
don't
need
this.
We
will
discuss
key
authorize
shortly.
We
said
that
we
don't
have
the
project
path,
we
do
have
IDs.
That
has
to
be
an
array,
so
a
very
quick
World
on
arguments.
So
you
give
a
name
which
is
the
one
that
will
be
used
on
the
schema.
Then
you
have
to
give
a
type
so.
A
A
So
you
can
think
that
we,
we
could
use
types
I,
think
there
is
string
yeah.
That
would
work,
but
the
global
ID
is
basically
a
smart
string.
We
can
see
one
here.
A
So
this
is
the
global
ID
of
of
this
model
and
this
primary
key
and
just
with
this
string
we
can
load
the
the
object,
no
problem,
because
we
do
have
the
model
and
we
do
have
the
the
ID
and
that's
why
we
won't
hear
a
global
ID
and
we
need
to
state
which
model
we
expect.
A
A
Required
the
schema
allows
you
to
to
say:
if
you
expect
you
can
have
multiple
fields,
and
you
can
you
can
say:
okay,
this
field
is
required,
I
need
it
all
the
time.
This
input
field
and
this
input
field
is
optional.
That's
basically
the
required
thing
here.
We
only
have
IDs
so
yeah,
it
is
required.
Otherwise
we
we
can't.
We
can
do
anything
and
then
the
description,
it's
useful
for
the
schema,
because
you
will
get
the
description
there,
the
it's
the
Side
Bar
that
I
open
previously
like
exploring
the
schema.
A
We
will
see
the
description,
but
the
other.
The
other
thing
is
that
we
are
going
to
generate
some
documentation
out
of
this
description
and
the
tools
that
generate
descriptions
will
read
this
field.
So
this
way
the
documentation
on
the
handbook
is
updated
for
us.
So.
A
That's
the
result,
let
me
close
everything.
Okay,
so
we
don't
have
project
paths.
We
just
have
IDs
now
destroy
package
yeah.
So
that's
the
right
permission,
but
we
can't
work.
We
are
not
working
on
a
single
object
like
we
do
here.
The
authorized
find
is
for
a
single
object
for
multiple
objects.
A
A
A
To
extract
the
model,
yeah
model
ID
and
then
it's
using
the
model
class
directly
yeah,
that's
not
really
recommended.
We
should.
We
usually
need
to
use
a
finder.
So
a
finder
is
like
it's
like
a
service
class
that
is
highly
specialized
to
just
fetch
objects.
That's
it
services,
do
whatever
logic
you
need
to
do
so.
A
A
I
guess
the
first
thing
we
can
do
here
before
any
passing
is
checking
the
the
amount
of
IDs
that
we
receive.
It's
exactly.
This
line
actually
I'm
going
to
copy
it
I'm
losing
this
morning.
So.
B
A
This
we
don't
need
this
because
we
don't.
We
are
not
going
to
use
the
also
as
find
why
we
do
that
here,
because
passing
Global
ideas
is
not
free.
It's.
B
Like
you
are
spending
some
processing.
A
If
all
is
good,
we
can
I,
guess
yeah.
We
we
can
pass
the
the
IDS
so
basically
the
same
thing
that
we
have
on
the
other
file.
B
A
A
B
Bad
idea,
this
is
a
good
idea,
so
I
will
refactor
all
that
later,
but
we
can
keep
that
for.
A
Now
and
gids,
so
we
are
going
to
get
the
packages
now.
The
thing
is
that
I
don't
think
we
have
a
finder.
B
B
One
question:
wouldn't
that
additional,
since
it
applies
some
default
sourcing
and
ordering
what
it
apply,
some
kind
of
additional
slowness
which
we
not
really
need,
because
for
us,
the
order
doesn't
matter
for
the
bulk
destroy
operation.
B
A
I
guess
so
you
you
are
right,
it's
going
to
add
an
order
on
the
final
SQL
query.
But.
To
answer
your
question.
We
would
need
to
run
the
database
review,
so
we
will
need
to
go
through
the
analyzing.
The
the
query
itself
decorated
art
is
indexed.
A
It's
context,
knowledge
so
I'm,
not
sure
that
we
are
going
to
lose
that
much
performance
and
actually.
A
Will
it
matter
so
the
thing
when
you
work
with
collections
in
in
gitlab?
There
is
one
thing
that
to
to
have
in
mind
is
that
you
don't
work
on
the
collection
directly
from
the
database
because
yeah
locally,
we
might
have
two
packages
and
that's
fine
right,
but
on.com.
A
B
The
batch
Loop
class
helper.
A
Yeah
I
guess
that's
something
to
take
into
account
from
my
knowledge:
I
think
the
the
default
sorting
will
work
just
fine,
but
I
would
still
and
actually
I
will
do
it
on
this
amount.
Because
that's
a
new
query,
we
will
need
the
database
analysis
so
that
we
know
that.
Okay,
this
query
disquarified,
it's
fine.
What
is
more,
what
bothers
me
more
are
the
the
including.
A
A
Yeah
I'm
not
happy
with
this,
because
we
don't
necessarily
want
to
include
in
this
case,
because
we
just
won
the
package.
We
are
not
going
to
read
the
project
route
or
the
tags.
A
B
A
A
So
yeah
the
thing
is
that
the
mutation
will
need
a
finder
and
the
service.
My
idea
for
this
session
is
that
I
don't
want
to
spend
too
much
time
on
those
two
things,
because
there
are
they're
like
additional
things
out
of
graphql
I
wanted
to
focus
this
session
on
graphql.
But
you
tell
me
if
you
want
to
go
into
details
on
finders
and
services.
That's
fine
too!
A
It's
as
as
you
want.
My
idea
was
yeah.
I
can
quickly
perhaps
update
this
finder
just
to
make
it
work,
but
then
I
will
either
create
a
no
create
a
new
one,
modify
it
so
that
this
thing
is
optional,
because
I
really
don't
want
this
to
be
executed.
B
A
A
A
Here,
filter
by,
let's
say
that
it's
IDs-
probably
this
is
specific
to
this
finder,
so
I'm
not
going
to
add
this
to
the
we
do,
have
a
a
module
or
a
concern
or
whatever
you
want
to
call
this.
It's
a
ruby
module
that
is
included
in
different
helpers
to
provide
this
filtering
methods
but
filter
by
IDs
yeah.
That's
not
that
often
that
we
need
to
do.
B
That
so,
let's
keep
it
here,
so
we
just
need
packages
yeah,
let's
keep
it
something
simple
ID
and
we
will
need
the
IDS
right.
B
I,
don't
think
we
need
a
fetch.
We
can
directly
just
do
this.
A
Yeah,
otherwise
we
can
return
all
oh
yeah
yeah,
even
the
wear
on
finders.
No,
you
don't
do
that,
but
we
do
have
a
scope.
That's
fine!
It's
just
that!
It's
always
a
different
one.
A
A
B
A
Yeah
I
need
to
think
if
we
need
a
new
finder
or
we
modify
this
one.
But
making
the
project
optional
is
is
a
bigger
change,
because
this
finder
has
the
project
as
a
you
see
as
a
like
main
parameter
main
input.
It's
like
it's.
It
is
centered
on
Project,
so.
B
Going
to
use
the
the
word
directly
here,
package
pad
ID
in
model-
IDs-
kids-
that's
it
I-
will
remove
this
and
this
one,
because
it's
not
I'm
useful.
A
Okay,
we
do
have
the
packages,
then
we
need
to
pass
this
one
to
the
sorry.
A
Correct
you
noticed
that
I
didn't
check
the
permissions.
Yet
that's
that's
right.
My
idea
is
to
have
them
checked
in
the
service,
which
is
something
that
we
can
do.
Let
me
show
you
what
marking
one
single.
A
One
so
in
in
the
package
registry,
we
don't
destroy
packages
directly
because
we
do
have
files
and
files
are
linked
to
object
storage,
so
we
can
delete
them
within
the
web
request
because
that's
that's
a
bit
too
many
operations
in
one
go,
and
here
we
are
actually
trying
to
destroy
multiple
packages,
so
that
would
be
even
more
operations
to
do
in
one
go
so
instead,
what
we
do
is
that
we
we
mark
them.
It's
like
flagging
them
for
for
Destruction.
A
Authorization
part
so
checking
if
the
user
can
delete
actually
delete
the
package
or
not.
Then
we
have
a
few
things
to
to
do
like
marking
the
actually
marking
the
package,
updating
the
the
white
column
to
pending
destruction,
and
then
we
do
need
also
to
Mark
the
package
files.
A
Yeah,
that's
that's
correct
and
we
need
to
sing
the
yeah.
That's
for
Maven
packages.
That's
something
specific
for
Maven.
In
very
short
words.
Maven
has
a
other
file
that
we
list
all
the
available
packages.
So
if
you
delete
a
package,
we
need
to
remove
that
packaging
version
from
that
file,
so
this
function
will
include
a
job
that
will
just
do.
A
Well,
I
will
I
will
not
go
into
details
on
those
lines,
but
this
line
is:
is
a
SQL
update
standard
thing?
This
one
is
including
a
background
job.
This
one
is
becoming
a
background
job,
so
this
service.
At
the
end,
it's
only
doing
one
SQL
query.
A
B
Way
but
okay,
just
for
my
packages
for
Destruction.
B
Yeah
yeah
again
I'm
lazy.
So
let's
have
this.
B
Actually
I
will
just
copy
everything
and
modify
as
we
go.
So
it's
packages.
A
Yeah
I'm
going
to
to
skip
the
this
thing,
but
it's
actually
we
do
have
a.
We
do
have
parent
class
to
Define
services,
and
this
parent
class
has
a
specific.
A
And
so
one
of
the
parameters
are
the
container,
which
is
like
domain
actor
that
you
want
to
open,
like
this
service
want
to
works
on
this
actor
or
this
object.
So
the
the
object
is
called
container
for
the
base
container
service
so
because
I
don't
want
to
have
container
everywhere.
I
just
put
an
earlier
so
that
I.
A
So
first
thing
we
will
have
a
user
yeah,
that's
correct
and
we
we
need
to
know
if
the
user
can
destroy
the
package.
So
obviously
we
can
do
packages.project
that
doesn't
work
because.
B
Check
this
permission.
A
But
could.
B
We
do
better,
that's
that's
the
question
so.
A
What
I
had
in
mind
is
something
like
this,
so
first
getting
the
project,
ideas.
B
A
A
Which
means
that
we
don't
want
duplicates,
because
you
don't
want
to
check
the
the
permissions
twice,
although
we
don't
have
any
performance
penalty,
because
the
permission
framework
will
actually
cache
all
evaluations.
So
if
you
check
the
destroy
package
against
project
I
project
a
and
then
at
a
later
time
you
check
again
the
first
evaluation.
The
result
of
that
evaluation
was
cached,
and
so
the
second
one
is
almost
free.
The
Char,
the
cache
is
checked
and
there
is
a
hit
and
you
will
get
the
result
return.
A
A
Yeah
we'll
take
again
a
shortcut
and
I
think
there
is
a
better
way
to
do
this,
but
let's
do
this
so
we
load
all
the
projects
and
then
we
ask
if.
B
A
Yeah
we
could
do
that.
The
only
doubt
I
have
is
that
the
plug
will
I'm,
not
sure.
If
that
you
can
customize
the
query
that
plug
will
do.
What
we
could
do
is
Select
to.
A
Here,
yeah,
that's
good
yeah!
Probably
I
will
need
to
refactor
all
this
because
he's
not
happy
that
I'm
calling
an.
A
B
A
Yeah
here
I
will
need
to
think
about
it,
because
that's
something
I
know
I
want
to
reuse
this
service
on
cleanup
policies
and
cleaner
policies.
We
are
not
going
to
work
on
20
packages
Max,
we
can
work
on,
like
thousands.
B
Take
everything
here
up
to
this
one
put
it
here.
A
Yeah
again,
this
is
this
is
a
shortcut,
but
I
will
not
create
the
the
Mr
with
this,
because
we
should
really
avoid
each
on
collections
that
you
don't
know
the
the
final
size
for
our
case
here.
It's
fine
because
we
limited
the
IDS
to
20.
So
it's
fine
to
do
an
age,
but
I
know
that
I
want
to
reuse
this
service
on
cleanup
policies
and
it's
not
20
is
is
like
any
number.
It's
it's
arbitrary,
so
we
cannot
have
an
each
here.
We
need
to
have
something
else.
B
Each
Loop
I'm
quite
sure
that
we
will
need
that.
A
A
So
probably
I
will
do
that
and
and
streamline
this
one,
because
this
one
is
an
update.
So,
instead
of
having
that
many
updates,
we
can
just
pack
all
together
in
one
single
update
this
one
I
will
probably
have
a
way.
There
is
a
way
to
include
multiple
jobs
in
a
single
call.
I,
don't
want
to
include
them
one
by
one.
It's
similar
to
the
SQL
aspect
like
include
them
all
by
one,
but
for
the
sake
of
keeping
things
short.
B
I
will
just
use
it
each
here
and
well
that's
fine!
For
our
case,
let's
go
back
to
our
limitation
mutation.
Where
are
you
here?
So
no?
No!
No!
No!
You
are
not
here.
You.
A
And
the
parameters
that
we
need
to
give
so
I'm
going
to.
A
First
one
well:
okay,
I
didn't
want
to
do
that,
but
I
guess
I
will
just
open
the
basement
panel
service
check
the
initialize
and
that's
it.
So
it's
all
keywords:
okay,
so.
B
Container
packages,
current
user,
end
user
and.
A
That
should
be
good
and
then
with
the
response,
so
yeah
I
guess
result
is
a
better
one.
So
the
result
will
return.
A
It's
actually
an
object
that
where
you
have
a
study
tools
on
it,
so
you
can.
You
can
check
if
it,
if
you
have
an
error
or
not
all
right,
I
think
I'm
missing
yeah
I'm,
just
this
is
just
the
service,
but
you
need
to
actually
execute.
B
A
A
Same
thing,
it's
basically
reading
the
the
status.
If
we
do
have
an
error
or
not,
if
we
do
have
one,
we
can
have
messages
and
then
we
return
the
we
return.
A
Last
thing:
this
is
a
new
mutation
that
we
need
to
put
in
the
schema
right,
because
we
do
have
a
mutation
here.
But
if
you
look
for
destroy
packages,
no,
we
do
have
the
orders.
A
This
is
very
simple,
since
every
every
it's
like
every
object
in
the
graphql
schema
is
mapped
to
a
class.
We
do
have
a
query
type.
That
is
a
class
that
will
actually
have
all
the
queries
that
are
possible
and
we
do
have
a
mutation
type,
I
guess
yeah
same
thing,
but
for
mutation,
mutations,
so
yeah
there
is
a
bit
of
order
in
here.
So
let's
put
here,
let's
put
everything
together.
We
do
have
the
destroy
here.
A
Okay,
I
think
we're
good.
So
what
we
can
do
is
just
reload
the
editor.
The
editor
itself
will
query
the
the
graphql
server
hey,
give
me
the
the
new
schema
and
we
should
see
the
our
mutations
here
when
you
work
on
on
graphql.
This
is
very
handy
because
this
loading,
if
it
fails
that
means
that
something
that
something
went
wrong
with
either
your
declaration,
your
mutations
or
you
I,
don't
know
the
arguments
or
something
here
it
it.
It
has
all
loaded.
So
our
mutation
is
a
valid
one.
It
was
properly
loaded
and.
B
A
The
input
this
is
an
object
that
is
created
for
us.
The
input
is
the
the
arguments
that
we
ask.
You
can
see
the
IDS
here
you
can
see.
That
is
a
an
array
and
those
Bank
symbols
means
that
this
is
required.
A
So
the
array
is
required
and
even
one
element
is
required
so
that
clients
can
send
a
null
ideas
and
they
can
send
an
empty
array
that
would
be
invalid.
So
we
can
try
this
now.
Let
me
get
the
the
global
IDs
because
I
don't
recall
them
so.
A
A
A
Going
so
we
can
just
use
IDs
and
then
just
pass
an.
B
And
structure
with
we,
which
we
expect
to
be
empty
yeah
so
like
this.
B
A
B
Fine,
so
let's
go.
A
B
Right
yeah
this
these
ideas.
A
Arrows
nothing,
so
we
can
check
the
logs.
We
can
see
that
the
packages
were
updated.
A
So
that's
good,
that's
what
we
want,
but
again
we
we
can
see
here
the
effect
of
that
each
loop
on
the
collection
is
that
these
lines
and
these
lines
are
similar.
So,
instead
of
having
a
single
update,
we
can
have
a
single.
Instead
of
having
multiple
updates,
we
can
have
a
single
one.
B
B
A
A
So
we
we,
basically
the
the
implementation
on
the
graphql
side
is
done.
Is
that
that's
good?
The
only
thing
is
missing.
Is
the
the
refactorings,
because
I
I
took
two
shortcuts
here
for
the
finder
and
in
the
service
for
looping
on
the
packages,
and
then
when
this
refactoring
is
done,
we
will
need
to
create
all
the
specs.
But
well,
since
we
are
out
of
time
I
guess
we
need
to
stop
here,
yeah.
Well,
so
that's
basically
the
how
you
you
work
with
graphql.
A
We
can
have
a
quick
word
on
specs,
so
specs
for
graphql.
It's
about.
Basically,
you
are
going
to
have
specs
on
two
levels.
One
of
them
is
the
mutation
itself.
It's
like
it's
almost
initializing
this
class
and
calling
the
resolve
function,
basically
that
what
you
will
do
and
the
other
level
is
running
at
the
it's
like
running
at
the
graphql
controller
level,
where
you
actually
send
the
query
to
the
controller
and
say
hey,
it's
like
doing
what
we
did
here.
A
You
send
this
and
you
expect
you
just
check
the
response,
and
this
will
allow
checking
that
the
schema
was
correct,
that
everything
is
connected
together
properly.
A
It's
a
it's
a
request,
spec,
so
I
would
say
that
it's
more
on
the
integration
side,
because
you
check
everything
you
you
check
that
everything
is
properly
connected,
whereas
the
mutation
spec
is
really
you
take
the
mutation.
B
Class
and
just
see
how
how
it
behaves.
A
B
I
have
a
question
on
so
there
is
a
graphql
API
documentation
file
like
that
gets
updated.
So
how
do
you
oh.
A
Yeah
yeah
good
question,
so
here
we
do
other
changes
and
we
do
it's
a
it's
a
rake
task.
The
only
thing
is
that
I
don't
remember
where
it
is.
What
is
the
name?
No
I.
B
Yeah
I
guess
it's
not
I,
don't
know
where
the
font
is
the
font
size.
A
Grab
I
think
it's
graphql.
A
But
no
worries.
Actually
this
is
checked
by
Danger
on
graphql
changes,
so
danger
Will
detect
that
there
is
a
change,
and
so
it
will
tell
you
hey
you.
You
forgot
to
run
this,
so
we
have
actually
three
things:
there
are
these
ones
yeah
the
the
schema
there
are.
A
There
are
two
formats,
there
is
a
Json
format
and
there
is
the
like
the
guava
creel
format,
which
is
basically
what
we
see
here
when
we
create
queries
same
thing,
but
with
everything
that
we
can
do
so
we
do
have
two
tasks
for
update
those
schema
now.
Actually
we
do
have
one
for
dumping.
The
schema
in
in
those
two
formats
and
the
other
one
that
we
will
need
is
the
compiled
dogs.
So
it's
gitlab,
graphql,
compile
docs.
If
you
want
that.
A
Okay,
so
while
it's
doing
this
thing,
it
will
update
this
documentation,
it's
a.
A
That's
limitation,
you
see,
you
have
the
list
of
arguments
with
that
description,
that's
where
the
description
field
is
used
and
what
is
returned
and
those
are
links
tools
or
you
can
click
you
out.
This
is
a
package
file
ID,
it's
a
global
ID
and
here
is
an
example.
A
A
If
you
have
any
doubt
on
the
graphqlmrs,
because
we
have
many
many
many
custom
options
and
things
that
we
can
use
at
GitHub,
don't
hesitate
to
use
a
backend
maintainer.
That
has
a
graphql
expertise.
A
We
do
have
a
few
ones.
So
I
would
say
that
for
all
simple
things
like
a
new
query
or
adding
a
new
field
that
you
can
return
in
a
query,
that's
fine!
Anyone
can
review
that,
but
for
more
complex
mutations
or
more
complex
access
like
sometimes
you
want
to
access,
really
nested
objects,
but
at
the
same
time
you
want
to
avoid
and
plural
n
plus
one
situations.
Things
like
that.
B
The
weapon
any
other
question
I
have
one
question
yeah.
Would
you
mind
to
go
back
to
the
editor
yeah.
B
Yeah
to
the
code
editor,
we
implemented
kind
of
the
strict
rule
that
if
the
amount
of
IDs
is
more
than
Define
it,
then
we
just
trust
an
error
yeah.
What
would
be
your
thoughts
on
to
make
it
slightly
softer,
for
example,
and
still
accept
the
request
but
kind
of
partial,
accept
request
and
still
delete
some
amount
of
the
packages
but
and
together
also
like
rice
and
errors
that
only
this
amount
allowed,
but
so
you
know
kind
of
success.
Blood
Plus
combine
it
with
error,
just.
A
In
this
case,
the
the
max
amount
of
20
was
not
chosen
randomly
it's
actually
the
amount
of
packages
that
can
be
selected
on
the
front
end
for
Destruction
and
so
ultimately
the
front
we
will.
We
want
to
implement
that
front-end
feature.
So
these
backend
changes
are
supporting
that
front-end
feature
and
yeah.
For
the
first
iteration,
we
decided
to
start
with
what
the
front-end
needs
and
limit
to
that.
A
If
then,
users
come
back
and
hey
I
want
to
delete
like
I,
don't
know
thousands
of
packages,
we
can
look
into
into
that
and
see
how
the
system
reacts,
but
I
guess
it's
part
of
the
of
the
iteration
value.
The
first
iteration
is
super
simple
and
it's
the
front-end
needs
and
that's
fine.
The
only
extra
bonus
here
is
that
that
service
that
deletes
multiple
packages,
I
already
know
that
we
are
going
to
use
that
on
cleanup
policies.
A
So
if
we
can
take
into
account
the
scale
of
of
the
packages,
the
query
that
we
receive,
that
would
be
way
better,
so
that
issue
will
definitely
need
to
be.
A
Okay,
well
then,
there.
B
Are
no
other
questions,
I
will
stop
sharing
and
there
are
just.
This
is
the
end
of
our
session.
So
I
will
stop
the
recording.