WWDC2018 Session 303

Transcript

[ Music ]
[ Applause ]
>> Good afternoon.
I'm Geoff Coffey.
I'm an engineer on App Store
Connect and I'm here to talk to
about automating App Store
Connect.
And I got to be honest with you,
I'm really excited about what
we're going to talk about today.
So let's start by talking about
where we are with automation in
App Store Connect today.
As I'm sure you all know, you
can use Xcode to upload your
builds to App Store Connect and
to download your crash reports
and we have the Transporter tool
that lets you automate uploading
the metadata.xml and also
automate your build uploads.
And then we have Reporter, the
command line tool for
downloading your sales and
financial reports.
And these tools are great.
A lot of you use them but we've
heard from you that you want
even more.
You want access to more areas in
App Store Connect and you want
to integrate with more diverse
workflows.
And so we're really happy to
introduce the new App Store
Connect API.
[ Applause ]
We're excited too.
So this is a standards-based
REST API for App Store Connect.
And if you ask me, that's the
best part about it, it's a stock
standard REST API with JSON
responses, so it's going to feel
familiar to a lot of you right
out of the box.
That also means you can use this
API from any platform, almost
any programming language, and
using the tools that you're
probably already using today.
And of course, the API needs to
be secure.
So we use industry-standard JSON
web tokens for authentication.
And that just means you don't
have to pass usernames and
passwords around, and you don't
have to have your code tied to
any specific person on your team
but you still maintain control
of who can access your data and
what they can do.
From an ease-of-use standpoint,
we focus really closely on
consistency with this API.
We have a single unified REST
resource model, which just means
that you can take what you learn
in any one part of the API and
apply it to every other part.
And we've also built
discoverability into the API
itself, in simple ways like when
we return JSON data to you, it's
nicely formatted and indented so
if you need to, you can dump it
out to the console and read it
right on the screen and we
include links and those
responses to related information
to help you figure out how the
parts fit together.
And, of course, the API will be
fully documented.
If you haven't seen this
already, the documentation
platform that you already use at
developer.apple.com and in Xcode
was extended this year to also
include Apple's REST APIs.
So the same format you're
familiar with your framework
docs will apply to the App Store
Connect API as well.
Now we started with a focus on
the areas of App Store Connect
that don't already have an
automation story and that you
have to visit over and over
again and in particular we're
starting with these four areas
you see here.
So let's look at what all is
included.
First, we have comprehensive
coverage of TestFlight.
You can manage your testers and
groups.
You can submit your builds for
review.
And if you saw the session
yesterday, the What's New in App
Store Connect Session, you know
we just announced a new public
links feature for tester
acquisition.
And this works hand-in-hand with
the API.
You can use the API to manage
your public links and you can
use the two of them together to
run your beta test program in
whatever way works best for you.
On the Users and Roles side, you
can add and remove users and
keep the permissions on your
users in sync with your actual
organization.
And as we announced yesterday,
this includes your complete
unified user base across
developer website and App Store
Connect.
So you have one set of users and
one set of roles.
[ Applause ]
We have provisioning APIs that
let you add development devices
and register bundle IDs and
manage your certificates and
profiles, and then we have
reports APIs that let you
download the sales and financial
report files.
And if you use the Reporter tool
today, this will feel really
familiar to you because the
parameters you send to Reporter
are very similar to the ones you
send to the API.
So it's really easy to make the
switch.
And I said there were four
things and this last part isn't
really part of the API itself
but I wanted to bring it up
because it's an important part
of our automation story.
We've made a couple of important
changes the Transporter to help
smooth all of this out for you.
First of all, Transporter will
officially be supported on
Linux.
And also, you can take the API
tokens that you use for the new
API and send those through to
Transporter and it can use those
for authentication as well.
It just makes the process easier
to manage for you.
Okay, we have a whole bunch to
get through.
We're going to go kind of fast
today.
I apologize for that but we have
a lot to cover.
We're going to talk about
getting data and changing data
with the API.
We'll talk about relationships
which is how the different parts
of the API fit together and how
you work with those.
We'll talk about how to handle
errors, how to get access to the
API and authenticate your
request, then we'll wrap up with
some best practices.
So, you ready to get started?
[ Applause ]
So like I said, we're going to
start with getting data and that
means we start right here,
api.appstoreconnect.apple.com.
This is the home base of the API
and from here we want to
construct a URL.
First we will add a version.
Now all API endpoints have a
version and right now that's
always v1.
But inevitably as App Store
Connect grows and changes over
time, we'll have to make changes
to the API that might cause your
code to stop working.
So when that ever happens, we'll
change this version number and
the old version will keep
working for a period of time so
you have time to adjust to our
changes.
Now after the version, we have
to add something called the
resource type name.
This is a really important
concept in the API.
The resource is like the
fundamental unit of the API.
Conceptually, you can almost
think of the API as a big
collection of resources that you
operate on.
We have a whole bunch of
resources in the API.
Most of them map to things
you're familiar with in App
Store Connect and we're not
going to talk about all of those
today.
We'll focus on just a few and
we'll start with Users.
And so here we have a complete
API URL: api.appstoreconnect
.apple.com/v1/users.
This URL represents all the
users on your team.
And, of course, you can go get
this URL and you'll get back a
JSON object.
And the first thing you'll
notice about this subject is it
has a data property.
Anytime we send you a successful
response with data in it, we
include this data property.
In this case, it's an array of
user resources.
Now, you can only see one user
on the screen right now but if
the screen were much, much
taller, you'd see that all the
users in your team are in this
array.
Now I want to focus in on some
of the data we return to you
with each of these resource
responses.
Every resource has a type just
telling you what it is and an ID
that uniquely identifies this
resource across all of App Store
Connect.
Then we have the attributes.
This is probably the stuff that
you're most interested in.
For users, it's things like
their first name, last name, and
email address.
The values of these attributes
are usually simple types like
this, strings, numbers, dates
and times or Booleans but they
can also be complex types
sometimes, like arrays and
objects.
After the attributes, we have
relationships.
We're going to skip those for
now.
We'll come back and look at them
later.
And then we have links and in
particular what we call the
resource self link.
Now this is a URL that uniquely
identifies this particular
resource, in this case the first
user in the result here.
Every resource we send back to
you includes this resource self
link.
It always looks like this:
api.appstoreconnect.apple.com
and then the version, v1, and
then the resource type, users,
and then the identifier of that
resource.
And you can go get it and you
get back data that looks almost
exactly like what we just saw.
The only difference here is
we're seeing just this one user
now instead of all the users on
your team.
So that's two ways to get data.
You get a list of resources or
an individual resource, but of
course you're going to want to
change data as well.
And to do that, we lean on
common REST conventions, so this
will also feel familiar to a lot
of you.
You've already seen how to get
resources.
To create a new resource, you'll
use the http POST method.
To change a resource, you'll use
PATCH, and to delete a resource,
you'll use the DELETE method.
So let's try this.
Let's say we want to add a new
user to your team.
Now a quick aside.
We can't add the user directly.
Just like in App Store Connect
itself, you have to invite the
user to your team and then they
can accept that invitation.
So we're going to create a user
invitation resource.
It looks like this.
We do a POST because we're
creating.
And the URL is the user
Invitations resource URL.
And then we have to send in the
data for this user.
Now this data looks a lot like
what you've seen when we fetched
users before.
But there's one important
difference I want to point out.
We have a type user Invitations
but we don't have an ID.
Now Apple will assign an ID to
every resource you create for
you.
So you don't include that in the
POST.
We've also left off links
because they're not required for
creation.
And we've left off relationships
because they're not relevant in
this particular case.
If we run this request, we get a
response.
In particular, this is a 201
CREATED response.
That's just standard REST
behavior to tell you that the
resource was successfully
created.
And we also include the full
resource information in the
response data and this is
important for two reasons.
First, it gives you the ID and
the resource self link of the
resource that was created, which
is stuff you're probably going
to need later so you can come
back and operate on this
resource.
And also if you look at the
attributes, you may see
attributes in this response that
you didn't include in the POST.
For example with user
invitations, Apple will assign
an expiration Date to every user
invitation you create.
Now you don't set that, so you
don't include it in the POST.
And that's why this response
data is really important to you.
It shows you the complete
picture of this resource after
it's been created and all of our
rules have been applied to it.
Now if this user accepts,
they'll become a user on our
team.
And suppose we want to come back
later and modify them in some
way, like for instance you can
see from the attributes here
this user has the developer
role.
So let's change that so they
have the developer and the
marketing role.
We're changing an existing
resource.
So we do a PATCH request.
The URL this time is the
resource self link of the user
we're changing.
And if you look at the
attributes, we're only including
the roles attribute.
This request says change this
user so that they have the roles
of DEVELOPER and MARKETING.
We didn't want to change
anything else about the user, so
we specifically didn't include
the other attributes.
If we run this request, again we
get a successful response and we
get the full resource
representation of the resource
with our changes applied.
Now the last thing you probably
want to do with the resource is
delete it and this is the
simplest operation of them all.
We just do a DELETE request to
the resource self link and we
get a 204 NO CONTENT response.
If you're familiar with REST,
you know that any status code in
the 200s means success.
So this is the API telling you
that the user has successfully
been deleted.
And we didn't need to include
any additional data this time,
so we use the NO CONTENT version
of a success response.
Now before we move on to the
next segment, I'd like to invite
my colleague Sehoon Shon up to
show you some examples of how to
use these resources in
real-world scenarios.
Sehoon.
[ Applause ]
>> Thanks, Geoff.
Hi, everyone.
My name is Sehoon Shon and I'm a
software engineer in TestFlight
team and I'm here today to show
you the live demo on App Store
Connect API.
We'll look at one use case and
see how we can apply the API on
users resource.
Let's say someone in our team
has left our company and we'd
like to find this user and
remove this user from the team
in App Store Connect.
So let's go see a demo.
We'll begin by getting the list
of all the users in our team by
sending GET request to the users
resource, which is GET v1/users.
And this returns all the users
we have access to in our team.
Now let's try to find the user
we're looking for and we can
search by the email of the user
by applying the filter
parameter.
So this filter parameter of
email specified that we would
like to find the users that
matches JohnAppleseed@mac.com.
So let's send this request.
And we get a response with a
user that contains the email of
John Appleseed.
Now let's use the ID of this
user to get the instance of this
user, which is users/ID and this
should return the instance of
the user with a matching ID.
And we get a response with the
username John Appleseed.
So we found the user that we're
looking for.
Let's try to remove this user by
sending DELETE request to self
link of this user.
So we'll replace GET with
DELETE.
And this should remove the user
with the matching ID.
And we get a 204, which means
the deletion was successful and
NO CONTENT since the content of
user is no longer available.
Finally, let's confirm that the
user is indeed removed by
sending GET request to the self
link once again.
And now we get 404 NOT FOUND and
it looks like the user is indeed
removed.
So in this demo, we saw how to
get collections of user, how to
find instance of user, how to
search user by applying filter,
and how to remove user by
sending DELETE request.
And this concludes the demo on
how to use App Source Connect
API with the users resource.
And I'll give the stage back to
Geoff.
Thank you.
[ Applause ]
>> Thanks, Sehoon.
So now you know how to create,
read, update, and delete all
these various resources and it
and might feel like that's
basically it, that's all you
need to be able to do but isn't
the whole story and that brings
us to relationships.
Sometimes it's not the
individual resources that you're
most interested in but the
connections between them.
It helps if I give you an
example.
We have a resource called Beta
Groups.
These represent all your groups
in TestFlight.
We have another one called Beta
Testers that represent all of
the people who can test your
applications.
And as you know, you can put
those testers into groups.
So how do we model something
like this in the API?
Let's start by getting Beta
Groups.
We go a GET v1/beta Groups and
we get back an array of Groups.
And if we look at the first
group and in particular the
relationship section, we see
that this group has three
relationships: app, beta
testers, and builds.
We're only going to talk about
Beta Testers today.
So we'll pop that one open.
And again, we see another links
section.
These are links associated with
this beta testers relationship
on this first group in the list.
You'd have a section like this
in each of the groups in the
array.
There're two links here, the
first one we call the
relationship self link.
And it's a URL that represents
the relationship itself.
And we use this URL to operate
on this relationship.
Now let me explain that.
We said we want to add testers
to this group, right, but I want
to be clear.
The testers are already in
TestFlight and the group is
already in TestFlight.
So we want to take these
existing testers and put them
into this existing group and
that's a operation that doesn't
fit with any of the things we've
learned about already, if you
think about it, right, like
we're not creating or editing or
deleting testers and we're not
really editing the group either,
at least not the attributes of
the group.
So conceptually, you might say
that we're creating new
connections between this group
and its related beta testers.
And this is where the
relationship self link comes in.
It looks like this.
We do a POST request to the
relationship self link.
And if you look at the data
we're sending, it's these type
and id pairs of the two testers
in this case that we want to add
to this group.
So this request says take these
two testers and put them into
this group.
We don't have to include more
tester information because the
testers are already in
TestFlight.
If we run it, we get a 204 NO
CONTENT response again.
That's the API telling you that
the testers have been added to
the group.
I'm sure some of you are
wondering "What if I want to
take testers out of the group
instead?"
And the answer is you do it in
exactly the same way.
It's the same URL.
It's the same data format.
You'll just use the DELETE
method instead of the POST
method.
Now let's take a look at Beta
Groups again and look at that
second link.
This is what we call the related
link.
This URL represents the actual
related data, in this case the
testers in this group.
If we go and get this data, we
get back an array of beta
testers.
The format here looks exactly
like what you'd get if you did a
Get of v1/beta testers.
The only difference is we're
getting the testers in this
group rather than all the
testers in your TestFlight
program.
And I want to pause there and
make sure I'm being clear.
We're getting the testers in
this group and when I say "this
group," I mean the group whose
identifier is in that URL.
So this URL get the testers in
one group.
If I want to get the testers in
a bunch of different groups
using this mechanism, I'd have
to make a bunch of different
requests, which can sometimes be
inconvenient.
So we do have one more way to
get related data.
It's called the include
parameter.
It looks like this.
We do a GET of v1/beta Groups
and then we add this query
parameter: include = beta
testers.
And this tells the API while
you're bringing me back the beta
groups, also include information
about the related testers in
each group.
Here's what it looks like.
We get our array of beta
testers, of beta Groups, excuse
me, and if you look at the beta
testers relationship in the
first group, you see this new
section called data.
And this has the type and id
pairs of the testers in this
group.
Now if you could see the whole
response here, you'd see a data
section like this inside each
beta testers relationship inside
each group that's in this array,
right.
But this is just the type and
IDs.
I'm sure you're wondering where
the actual tester information
is.
And if we scroll all the way
down to the end of this
response, we also have a new
section called include.
And this is an array of beta
testers with the full tester
information.
More generally the include
section has a full resource
representation of every resource
that you have included by way of
relationships.
And then we can match by type
and id, figure out which testers
belong to which group.
Now you might be wondering why
we do this.
We have the data section with
all of our groups and then we
have the include section with
all of our included testers.
And we do this for an important
reason.
We have this test on the screen
John Appleseed and that tester
might be in multiple groups,
right.
The way we have this structured,
the data for John Appleseed is
only in the response one time,
no matter how many groups they
appear in, in the response.
Make sense?
Okay. Sehoon is going to come
back up now and show us some
more real-world examples with
relationships.
Sehoon.
[ Applause ]
>> Thanks, Geoff.
So for this part of the demo
we'll look at TestFlight and see
how we can create new beta
groups and add some external
testers and we'll see some
relationship between testers and
groups.
So let's go see the demo.
We'll start by creating a new
beta group by posting to the
beta groups endpoint which is
v1/beta Groups.
When we're creating a resource,
we also need to provide the
payload that looks like this.
We have the data with the type
of beta Groups and a set of
attributes.
And since the name is the only
required field when we're
creating a group, let's give it
a name and we'll simply call it
Test Group.
And I'll send the request now
and we get a 409 CONFLICT
response.
So let's look at the details.
It says, "You must provide a
value for the relationship app
with this request."
So in TestFlight, you cannot
create a beta Group that does
not belong to any app and, thus,
we must create a relationship to
an app while we're creating beta
Group.
And how do we do this?
We can include the relationship
in the payload like this.
So now we have the relationship
in the payload of an app with a
data type of apps and the id
specifies which apps the beta
Groups should be linked to.
So this will create beta Groups
with the name of Test Group and
link to an app with the id.
So let's resend this request.
And now we get a 201 CREATED
response.
In the response, we have the id
that is generated.
So let's copy this id.
So we just created a group
called Test Group.
But what if you don't like the
name of the group we just
created?
We can modify the existing group
by sending PATCH request to the
self link of this group.
We'll send PATCH and then beta
Groups/the id and we'll also
need to provide the payload that
looks like this.
This looks a lot like payload
for posting but we also need to
provide the id to make sure that
we're modifying the correct
data.
And let's paste the id of the
beta Group.
And the only information we'd
like to change is the name.
So let's rename it to WWDC
Group.
And I'm sending the request and
now we get a 200 response and it
looks like the name has been
updated.
So now we have the group that we
wanted.
Let's start adding some external
testers.
To create tester, we send POST
request to the beta testers
endpoint, which is v1/beta
testers.
And we'll also need to provide
the payload that looks like
this.
It has a type of beta testers
and a set of attribute.
So we'll create tester that's
called Kate Bell and this also
has a relationship to the beta
Groups and this will create Beta
Tester and also assign to the
beta Group at the same time.
So if you paste the id of the
beta Group we just created, this
will assign the tester to the
WWDC Group.
And we get a 201 CREATED
response and it looks like the
tester is created and also
assigned to the group at the
same time.
While we're here, let's add one
more tester and all we need to
do is simply replace this
attribute portion with a
different person's name and this
will create John Appleseed to
the same group.
And again, we get a 201 CREATED
response.
So we just added two testers to
the group and now let's confirm
that these two testers are
indeed inside the group by
sending GET request to the
related link between beta Groups
and beta testers.
So this link, /the id of the
group/betaTesters, this will
return all the beta Tester that
are assigned to the beta Groups
with the specified id.
And as you can see, we have John
Appleseed that's added earlier.
And this response we have a lot
of information including list of
attribute as well as
relationship.
But what if you only care about
maybe the email of the tester?
We can trim down the response by
applying the special parameter
called fields and this will
allow us to trim down the body
and only look at what we would
like to see.
If you do fields of beta testers
equals email, as you can see now
the response only contains the
email of the user and nothing
else.
And we have the two testers that
are added to this beta Groups.
So in this demo, we saw how to
create beta Groups and beta
testers and so some relationship
between testers and groups.
And this concludes the demo on
How to Use App Store Connect API
with TestFlight.
And I'll give the stage back to
Geoff.
Thank you.
[ Applause ]
>> Thanks again, Sehoon.
That was awesome.
So that's getting data, changing
data, and relationships.
It kind of covers the basic
features of the API.
But as you saw a glimpse in
Sehoon's demo, sometimes you
make mistakes and we can't
process your request.
So we're going to shift gears
now and talk about how the API
communicates these errors back
to you.
Anytime a request fails, you'll
get a response that looks like
this.
Now the first thing to notice is
that we'll send back an
appropriate HTTP response status
indicating what went wrong,
usually something in the 400s.
And this is often all you really
need.
Most REST client libraries have
a Did Succeed or it Is Success
function and you can call that
and it will correctly tell you
if the request was successful or
not.
But if you want to know more
about what went wrong, you can
look down into the response.
When a request fails, instead of
that data property we've been
seeing all along, we'll give you
an error's property.
This is an array of error
objects.
But there can be multiple of
them, each one representing some
problem with the request you
sent.
They have an id that uniquely
identifies this particular error
of this particular response.
You might log this away and if
you think there's a problem on
our end, send it to us.
It'll help us track it down.
More useful for you is the title
and detail.
These together give you an
English language explanation of
what went wrong.
From the title here, I can see
that I have something wrong with
my parameters.
And from the detail, it tells me
that I'm filtering by email and
right away I see that I spelled
email incorrectly.
So these are great values to log
and use in your troubleshooting
and learning the API, but you
don't want to use these in your
code.
You don't want to try and
interpret these with your code.
I don't make any promises that
we won't change the wording on
these messages over time without
warning.
For programmatic error handling,
you want to use the code
property instead.
This is a stable
machine-readable string that
represents what went wrong.
It's a hierarchical value with
dots between levels of
specificity.
So in this example, I can see
that I have a parameter error,
generally, and more specifically
one of those parameters is
invalid.
Now these codes can get very
long and very specific and
sometimes you don't care about
all that specificity.
In fact, usually you don't.
So we structure them this way so
that you can do a prefix match
on the code and be as generic or
a specific as you need to be for
your particular use case.
But if you need to be specific,
say so you can report back to
your own users with clarity
about what went wrong, we try to
give you enough information to
do that.
And we help with that also with
the source parameter.
And whenever possible, we track
this error back to the place in
the request that caused the
problem.
Here I can see that it's the
filter bracket email parameter,
specifically, that produced this
error.
The source can be a parameter
like this or it could be a JSON
pointer pinpointing the spot in
the JSON data you sent us where
the problem originates.
And that's basically everything
there is to know about the App
Store Connect API except how to
get to the App Store Connect API
and successfully send requests.
So Julie Richards is going to
come up on stage now and help
you with that.
Julie.
[ Applause ]
>> Hi, everyone.
I'm Julie and I'm an engineer on
the App Store Connect team.
I'm here today to talk to you
about access and authentication.
So at this point you've seen a
bunch of different examples of
endpoints that will be
available.
And when you're ready to start
testing out some of these new
features, you might start by
sending a simple GET request
like this; however, if you were
to simply curl this endpoint or
type it into your browser,
you'll end up with a response
that looks like this.
So as Geoff mentioned, we're
still missing one very important
step stat and that is
authentication credentials.
Now this step is necessary for
two reasons.
First, authentication
credentials give context to your
request.
After all, you don't want all
apps.
You want your app.
And most importantly, these
credentials secure the API and
ensure that no one but you will
have access to your data.
So to add these credentials to
your request, you'll need to
first create an API Key.
You'll then use that key to
generate tokens and those tokens
will need to be sent with every
request.
So let's start with API Key.
Each key is actually a public
key, private key pair.
The private key belongs to you
and will be used to add a unique
signature to your token.
The public key will be used by
Apple to verify that signature
and ensure that it was in fact
signed by the associated private
key.
To create one of the keys,
you'll need to log in to App
Store Connect and navigate to a
new API Keys tab.
Your admin users will be able to
manage your team's API Keys.
You can create new Keys and
revoke them when they're no
longer needed.
Each key will need to be
assigned a level of access and
this will determine what API
services the key can be used
for.
Once created, new keys will
appear in this list and the
private key file, that's the
part that belongs to you, will
be available to download.
Now it's important to note that
each private key can only be
downloaded once.
That is because these keys are
not stored by Apple.
In fact, your key is not even
generated until the moment you
decide to download it.
So you can think of these keys
like real keys.
They belong to you and they must
be managed and protected by you.
Also much like real keys, these
keys do not expire, so if the
key is lost or stolen it will
continue to have access to your
data until it is revoked through
App Store Connect.
So for this reason, it is very
important to keep your keys safe
and secure.
Once you have your private key
file, you'll be ready to start
generating JSON web tokens.
Now each of these tokens will
need to contain a few pieces of
information.
First, you'll need to add your
Issuer ID, that's your account
identifier, and this ID can be
found at the top of that new
page.
You'll also need to find or
you'll also need to add the ID
of your key.
This ID can also be found on
this new page and it is specific
to the key that you'll be using.
Now each token will also need an
expiration timestamp.
As I mentioned before, your keys
do not expire but these tokens
can only be used for up to 20
minutes.
And the last two pieces of
information are simply constant.
By that, I mean they will remain
the same across all tokens and
for all App Store Connect APIs,
the first is the Audience for
the token and that will always
be App Store Connect.
And finally, you'll need to
assign or you'll need to add the
algorithm that was used to sign
the token.
And for this, we have chosen to
use ES256.
Now this algorithm corresponds
to a JWT-supported algorithm
that we have chosen to have you
use but don't worry, you don't
need to implement this
algorithm.
Fortunately, JWT provides
multiple libraries across
virtually any language that
makes creating and signing these
tokens as easy as possible.
This example behind me is
written in Ruby and, as you can
see, all I need to do is pass in
these few pieces of information
along with my private key and
this encode method returns to me
a complete and signed token.
That token can then be added to
my request by simply placing it
inside of an authorization
header.
So now that we know how to
create these keys and how to use
these keys to add tokens to our
requests, let's go ahead and
give it a try.
Okay, so here's that new API
Keys page and I don't have any
keys yet.
So I'll go ahead and create one.
I'll call it demo and I'll have
to assign a level of access.
So here, if I were to choose
something like finance, I'd get
a key that has access to things
like financial reports or sales
reports but it won't have access
to things like beta testers or
builds.
I can add on levels of access or
I can choose admin and I'll have
a key that has access to all
APIs.
So I'm going to stick with
admin.
And when I generate my key, I
can see that my private key is
available to download.
As I mentioned earlier, my
private key can only be
downloaded once.
If I lose my key or accidentally
delete it, I can't come back
here to re-download it.
So for that reason, I'm prompted
to make sure that I'm ready to
download this now.
And I am, so let's go ahead and
download.
Now that I have my private key
in my Downloads folder, I can
pull up that script we saw
earlier.
And I'll need to copy over my
ISSUER ID.
That's the one that's shared
across your API Keys.
And I'll also need to copy that
ID of the private key I just
downloaded.
And once I have those IDs in
place, my private key will be
loaded in from my Downloads
folder.
And I'll generate a new token.
So if we pull up the terminal, I
can curl that apps endpoint.
And as we expected, we get that
401 response.
So let's call my script.
And I get a new token.
So I can take that token and add
it to my request
by putting it in an
authorization header.
Make sure I spelled that right.
And I get back the list of my
apps.
[ Applause ]
So as you can see, with just a
few easy steps I was able to get
access to the API and start
getting back real data.
Thank you.
Back to Geoff.
[ Applause ]
>> Alright.
Thanks, Julie.
Pretty cool, huh?
So that's access and
authentication.
And now in the few minutes that
we have remaining, I want to
talk about some best practices
when using the API.
We're going to start with those
keys.
Now as Julie said, those keys
belong to you and it's your job
to protect them.
Anybody who has the keys can
access your data.
So ideally, you're going to put
those keys in some kind of a
secure key store and your code
will check them out, use them in
memory, and never store them
anywhere, like in a database or
on disc.
If you do have to store the keys
on disc, make sure you check
your file system permissions
very carefully.
And, of course, if you have any
reason to think a key has been
compromised in some way,
immediately log in to App Store
Connect and revoke that key.
I also want to talk about the
tokens that you create from your
keys.
Now there's no reason that you
have to send a different token
with every request.
In fact, you'll get better
performance in your code and on
our end if you reuse those
tokens over and over again.
And usually this is really easy,
right.
You just generate a token at the
top of the script, send it with
every request until you're
finished.
And we let you control the
expiration time because you're
the best person to know how long
it should last, long enough to
complete that process and not
significantly longer than it
needs to be.
Of course, you might have
processes that run for longer
than 20 minutes or run
continuously and when that's the
case you'll want to structure
your code a little differently.
Maybe you'll generate a
20-minute token and use it as
needed and then throw it away
and issue a new one before the
old one expires, say every 18
minutes.
That way, you're getting maximum
token reuse for the best
performance and you're never
sending expired tokens.
The next think I want to talk
about is the links that we
include in the responses.
Now we've talked about these
today as a sort of nice form of
self-documentation, a way for
you to look at the data and see
what else is available, but
that's not the only reason
they're there.
They're actually intended to be
used by your code.
When you're doing a multistep
process, whenever possible take
the link we gave you out of the
response and use it for the next
part of the process.
This will help you in two ways.
One, it makes your code more
generically applicable to
different parts of the API.
And two, when that inevitable v2
API comes along, this will
reduce the amount of work you
have to do to adjust to the
changes.
And finally, I want to talk
about the documentation.
We've talked about the
consistency of this API today
and we really focused on that.
And so any time a resource can
do something, it will do it in
the same way as all the other
resources but of course not
every resource can do
everything.
You already saw an example of
this with users.
We had to create an invitation.
There's no API to create a user.
So the documentation is how you
figure this out.
It tells you what the resource
can do, what operations are
available, what parameters it
supports, and so forth.
And that's the App Store Connect
API.
It's a consistent
standards-based REST API.
We're really excited about it.
And one thing that we love about
this API is that we designed it
to be really flexible so that
you can take App Store Connect
and you can put it into your
workflow into the way that you
work and using the tools that
you like best.
We're really excited for you to
start doing that.
It'll be available to all app
developers this summer.
And I know you guys have
questions, so come and see us in
the App Store Connect Lab.
It's actually happening right
now.
So we'll head down there as soon
as I stop talking and we can
answer those questions.
We have a lab tomorrow as well
at 1:00 p.m. and also check out
the What's New in App Store
Connect Session if you missed it
yesterday.
It had some more about the API
and about App Store Connect
itself.
And bookmark this link because
we'll post the documentation
there just as soon as it's
available.
Thank you so much.
We'll see you in the labs.
[ Applause ]