Java REST API – Using Sessions with Jersey

apijavarestsession

I am starting to develop a REST API with Jersey to retrieve a schedule for a given sport tournament. The client sends a JSON containing a tournament with its different categories, domain, definitions and configuration. This will be unmarshalled by Jackson. And the response includes a JSON with the calculated schedule for that tournament, marshalled by Jackson as well.

I want to make the API as "API-like" as possible, in the sense of common APIs like weather APIs or maps APIs, where the client-server interaction is a direct, concise request-response-type operation, in this case that'd be "send a tournament, get a schedule", where no association between the client and the instantiated references (or conceptual associations) are left in the server at all. I guess the word for this would be "stateless".

However, I need some sort of reference to the tournament that has been sent in order to perform subsequent operations on that instanciated object. The case would be, for example, to retrieve the "next" schedule for the tournament. There are potentially many other cases.

Since I am using Constraint Programming to calculate the schedules, I can get all the possible combinations of schedules for a given tournament. But a direct operation as described just gets rid of the instance as soon as the schedule is returned in the response, therefore I wouldn't be able to invoke methods such as tournament.nextSchedules() because the tournament object simply wouldn't be there. So I was suggested to use sessions. Then, I assume I would have a map of session ID and a Tournament instance in my web service Jersey class:

@Path("eventscheduler")
public class EventSchedulerService {
    private Map<String, Tournament> tournaments = new HashMap<>();
}

Then, if I wanted to perform an action on a particular tournament I would just have to retrieve its corresponding mapping to a session ID, which can be passed in the URL as a @PathParam.

Here are my questions:

  • How could I do this with Jersey? How can I generate a session and store it as intended? Note that this has nothing to do with security. The sole purpose of using sessions is to be able to identify a particular reference of a Tournament.
  • How can I set an expiration time on a session? I wouldn't want to have a client forever bound to a particular tournament instance. Although I will probably make a method to explicitly unbound a client to a session, as well as getting rid of the mapping, I'd also want to have it expire and removed from the dictionary as well. How can this be done?

Note as well that no databases are being used and are not intended to be used since it's not the objective of this project and they shouldn't be needed.

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.

GET /tournaments/west_cost_regionals_2016

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

GET /tournaments/west_cost_regionals_2016/next_event

Using a session should be completely unnecessary.