Edited to address question updates, previous answer removed
Looking over your changes to your question I think I understand the problem you are facing a bit more. As there is no field that is an identifier on your resources (just a link) you have no way to refer to that specific resource within your GUI (i.e. a link to a page describing a specific pet).
The first thing to determine is if a pet ever makes sense without an owner. If we can have a pet without any owner then I would say we need some sort of unique property on the pet that we can use to refer to it. I do not believe this would violate not exposing the ID directly as the actual resource ID would still be tucked away in a link that the REST client wouldn't parse. With that in mind our pet resource may look like:
<Entity type="Pet">
<Link rel="self" href="http://example.com/pets/1" />
<Link rel="owner" href="http://example.com/people/1" />
<UniqueName>Spot</UniqueName>
</Entity>
We can now update the name of that pet from Spot to Fido without having to mess with any actually resource IDs throughout the application. Likewise we can refer to that pet in our GUI with something like:
http://example.com/GUI/pets/Spot
If the pet does not make any sense without an owner (or pets are not allowed in the system without an owner) then we can use the owner as part of the "identity" of the pet in the system:
http://example.com/GUI/owners/John/pets/1 (first pet in the list for John)
One small note, if both Pets and People can exist separate of each-other I would not make the entry point for the API the "People" resource. Instead I would create a more generic resource that would contain a link to People and Pets. It could return a resource that looks like:
<Entity type="ResourceList">
<Link rel="people" href="http://example.com/api/people" />
<Link rel="pets" href="http://example.com/api/pets" />
</Entity>
So by only knowing the first entry point into the API and not processing any of the URLs to figure out system identifiers we can do something like this:
User logs into the application. The REST client accesses the entire list of people resources available which may look like:
<Entity type="Person">
<Link rel="self" href="http://example.com/api/people/1" />
<Pets>
<Link rel="pet" href="http://example.com/api/pets/1" />
<Link rel="pet" href="http://example.com/api/pets/2" />
</Pets>
<UniqueName>John</UniqueName>
</Entity>
<Entity type="Person">
<Link rel="self" href="http://example.com/api/people/2" />
<Pets>
<Link rel="pet" href="http://example.com/api/pets/3" />
</Pets>
<UniqueName>Jane</UniqueName>
</Entity>
The GUI would loop through each resource and print out a list item for each person using the UniqueName as the "id":
<a href="http://example.com/gui/people/1">John</a>
<a href="http://example.com/gui/people/2">Jane</a>
While doing this it could also process each link that it finds with a rel of "pet" and get the pet resource such as:
<Entity type="Pet">
<Link rel="self" href="http://example.com/api/pets/1" />
<Link rel="owner" href="http://example.com/api/people/1" />
<UniqueName>Spot</UniqueName>
</Entity>
Using this it can print a link such as:
<!-- Assumes that a pet can exist without an owner -->
<a href="http://example.com/gui/pets/Spot">Spot</a>
or
<!-- Assumes that a pet MUST have an owner -->
<a href="http://example.com/gui/people/John/pets/Spot">Spot</a>
If we go with the first link and assume that our entry resource has a link with a relation of "pets" the control flow would go something like this in the GUI:
- Page is opened and the pet Spot is requested.
- Load the list of resources from the API entry point.
- Load the resource that is related with the term "pets".
- Look through each resource from the "pets" response and find one that matches Spot.
- Display the information for spot.
Using the second link would be a similar chain of events with the exception being that People is the entry point to the API and we would first get a list of all people in the system, find the one that matches, then find all pets that belong to that person (using the rel tag again) and find the one that is named Spot so we can display the specific information related to it.
Consider the first case. Each client gets a random ID that lasts for the duration of the session - which could be several days if you like. Then you store the information relevant to that session somewhere server side. It could be in a file or a database. Let's suppose you pass the ID via a cookie but you could use the URL or an HTTP header.
Session IDs/ Cookies
Pros:
- Easy to code both the client and server.
- Easy to destroy a session when someone logs out.
Cons:
- The server side periodically needs to delete expired sessions where the client didn't logout.
- Every HTTP request requires a lookup to the data store.
- Storage requirements grow as more users have active sessions.
- If there are multiple front end HTTP servers the stored session data needs to be accessible by all of them. This could be a bit more work than storing it on one server. The bigger issues are the data store becomes a single point of failure and it can become a bottleneck.
JSON Web Tokens (JWT)
In the second case the data is stored in a JWT that is passed around instead of on the server.
Pros:
- The server side storage issues are gone.
- The client side code is easy.
Cons:
- The JWT size could be larger than a session ID. It could affect network performance since it is included with each HTTP request.
- The data stored in the JWT is readable by the client. This may be an issue.
The server side needs code to generate, validate, and read JWTs. It's not hard but there is a bit of a learning curve and security depends on it.
Anyone who gets a copy of the signing key can create JWTs. You might not know when this happens.
There was (is?) a bug in some libraries that accepted any JWT signed with the "none" algorithm so anyone could create JWTs that the server would trust.
In order to revoke a JWT before it expires you need to use a revocation list. This gets you back to the server side storage issues you were trying to avoid.
OAuth
Often OAuth is used for authentication (i.e. identity) but it can be used to share other data like a list of content the user has purchased and is entitled to download. It can also be used to grant access to write to data stored by the third party. You might use OAuth to authenticate users and then use server side storage or JWT for the session data.
Pros:
- No code for users to signup or reset their password.
- No code to send an email with a validation link and then validate the address.
- Users do not need to learn/write-down another username and password.
Cons:
- You depend on the third party in order for your users to use your service. If their service goes down or they discontinue it then you need to figure something else out. Eg: how do you migrate the user's account data if their identity changes from "foo@a.com" to "bar@b.com"?
- Usually you have to write code for each provider. eg Google, Facebook, Twitter.
- You or your users might have privacy concerns. The providers know which of their users use your service.
- You are trusting the provider. It is possible for a provider to issue tokens that are valid for one user to someone else. This could be for lawful purposes or not.
Miscellaneous
- Both session IDs and JWTs can be copied and used by multiple users. You can store the client IP address in a JWT and validate it but that prevents clients from roaming from say Wi-Fi to cellular.
Best Answer
It should be unnecessary to use sessions for this scenario.
When the client creates a new Tournament resource (represented in JSON) it can PUT or POST that resource to the server. Which one you choose will depend on who is responsible for the unique identifier for the Tournament. If the client already knows what the URL should be for that Tournament (say it is based of the name) it can just PUT that resource to that URL on the server (eg.
/tournaments/west_coast_regionals_2016
)If the server determines the URL then the client should POST the Tournament resource to some collection resource (eg.
/tournaments
) and that resource generates a unique id for the resource and returns it to the client.Either way the client gets back the URL of the resource it just sent to the server. If it ever wants to access that resource again it just uses that URL.
And the server returns that resource to the client. If the server has worked out some schedule then it can further information to the body of the response, or the way some do it is to add a new resource that contains just the next event information
Using a session should be completely unnecessary.