jdee
jdee

Reputation: 12070

RESTful Quiz Representation

I'm building a quiz. A user can pick a subject and answer 5 questions. After each question they view the answer. I'm trying to stick to a strict RESTful representation of this workflow but cant really settle on a url scheme. For example:

User Joe picks the subject sport and is ready to see the first question. The url is

user/joe/subject/sport/question/1

When he submits his answer 'B' ( its a multiple choice quiz) , Joe is creating a new answer, we POST to

user/joe/subject/sport/question/1/answer/B

before viewing the correct answer at

user/joe/subject/sport/answer/1

we then view the next question at

user/joe/subject/sport/question/2

This is all obviously too complicated. How would you approach this problem in a RESTful manner?

Upvotes: 3

Views: 295

Answers (3)

Matt Ball
Matt Ball

Reputation: 359786

Start with this presentation. It's is a great resource for RESTful API design. With that in mind, here are some starting suggestions:

  1. RESTful URLs have an implicit hierarchy. Take the user information out of the URL. It belongs in the HTTP headers.

    /subject/sport/question/1
    /subject/sport/question/1/answer/B
    /subject/sport/answer/1
    /subject/sport/question/2
    
  2. I don't see any useful information added by the subject part. The subject is identified by (in your example) sport.

    /sport/question/1
    /sport/question/1/answer/B
    /sport/answer/1
    /sport/question/2
    
  3. Categories should be plural.

    /sports/questions/1
    /sports/questions/1/answers/B
    /sports/answers/1
    /sports/questions/2
    
  4. When you POST to answer a question, you're not POSTing to add a new answer resource (that is, defining a new possible answer). Aren't you are POSTing to an existing resource?

  5. You haven't mentioned anything about HATEOAS. If you're really going to implement REST, you should be doing things like providing "next" links in the hypermedia.

Upvotes: 1

graffic
graffic

Reputation: 1412

For me the basic idea in a REST service is the "resource". First you need to identify your resources.

So there is a user and she starts a new quiz.

  • POST /user/joe/quiz.
  • It returns: Location: /user/joe/quiz/1

Then the user selects a sports question, so you update your quiz to include a random (server selected) question.

  • POST /user/joe/quiz/1 -> Subject:sport
  • It returns: Location: /user/joe/quiz/1/question/1

The user answers:

  • PUT /user/joe/quiz/1/question/1 -> Answer B

Now rinse and repeat.

The resources we've got:

  • Users
  • Quiz for a user
  • Questions in a Quiz (The question is updated with an answer)

Upvotes: 1

Veraticus
Veraticus

Reputation: 16064

I would remove /user/joe from the routes entirely. You can get the current_user using Devise, Authlogic, or some other authentication framework.

Otherwise this looks okay to me, as it's only two nests which is readable enough. So you'd have:

GET subjects/sports/questions/1
POST subjects/sports/questions/1 # pass along params with {:answer => 'B'}
GET subjects/sports/answers/1

Upvotes: 0

Related Questions