CSE 154

Week 8 Section: Writing our own Trivia Web Service

Overview

In today's section, we will get more practice with PHP file i/o and write own own trivia web service. We will also practice making calls as a client to our web service using JS and AJAX.

Having written both the server-side and client-side programs for this website, this section will wrap up the course module on PHP web services!

First Things First, PHP Code Quality Review

First, we're going to review some PHP code quality guidelines for this course using an example of "poorly-implemented PHP code". The code is "externally correct", but has a variety of quality and documentation issues - many of these are common deductions in the PHP HW assignments.

You can find the source PHP code here. How many issues can you identify and explain as poor code quality?

Exercise 1: Starting trivia.php

Now that we've reviewed some common PHP code quality issues, let's write a PHP web service! To get started:

  1. Create a file called trivia.php (remember to set error_reporting(E_ALL) at the top!).
  2. Download this trivia.zip folder of subdirectories containing trivia information for different topic categories.
  3. Write initial PHP code to print out the contents in of a random file in the trivia folder (recall the glob and scandir functions for accessing files in directories). You may also find array_rand useful, as it selects a random index of a passed-in array. Also recall file_get_contents for getting the contents of a file as a string.
  4. Test your service by refreshing the page several times and making sure you are getting random questions and answers.

Exercise 2 Part I: Adding a 'mode' GET Parameter (mode=categories

Modify the trivia.php web service to take a required GET parameter called mode. When the user passes in a mode value of categories, the web service should output a plain text list of all of the subdirectory names in the trivia/ folder.

astronomy
biology
chemistry
computerscience
culture
history
internet
pokemon
random

example output (mode=categories)

Exercise 2 Part II: Adding a 'mode' GET Parameter (mode=category)

Next, add a check such that if mode is passed as category, an optional name parameter can be passed to choose the category name to return the contents of a random file for that specific category instead of a random category.

If the name parameter is not passed, your web service should continue to choose a random category as before.

Exercise 2 Part II: Error Handling

If the mode query parameter is missing or does not have a value of either categories or category print out a 400 error message, "Error: Please provide a mode of categories or category".

Otherwise, if the mode query parameter is passed with a value of category and the optional query parameter name is passed a value that does not correspond to a category directory in the trivia directory, print out a 400 error message, "Error: Unknown category " (replacing <category-name> with the passed value for name).

Exercise 3 Part I: Output JSON for Question Data

In this part of the exercise, we will practice outputting our data in a more useful JSON format. Recall that JSON is much easier for clients to process than plain text. First, we'll focus on changing our response when for mode=category.

Any valid response for this mode should output the random question and answer in the JSON format displayed below (example for request to trivia.php?mode=category&name=pokemon):

{
  "question" : "What Pokemon comes first in the Pokedex?",
  "answer" : "Bulbasaur"
}

output (JSON)

Exercise 3 Part II: Output JSON for Categories Data

Next, update your code for handing mode=categories to now output JSON data in the format below:

{
  "categories" : [
    { "astronomy" : 2},
    { "biology" : 4},
    { "computerscience" : 10},
    { "culture" : 5},
    { "history" : 8},
    { "internet" : 9},
    { "pokemon" : 8}
    { "random" : 3}
  ]
}

example output (JSON)

The keys (categories) are the names of the folders in trivia directory. The values are the number of files in each category folder.

Exercise 4: Using Our Web Service as a Client (trivia.js)

Next, we'll use a starting trivia.js that has functions provided to switch between different views and display questions/answers for trivia. However, this file is missing... trivia. Let's use our new trivia web service for it to fetch trivia from!

Note: For now, ignore the "Add Trivia" button. In Exercise 5/6, you can handle POST requests to finish the "Add Trivia" feature for more practice with POST!

Trivia-It webpage

Exercise 4: Starter Files

In this part, we'll focus just on using our GET parameters for the "List Categories" feature. Download the starter HTML/CSS/JS here and make sure these are located in the same directory as your trivia directory and trivia.php file.

Exercise 4 Part I: Listing Categories

The provided trivia.html (styled with trivia.css) has three main sections: #category-view, #question-area, and #new-trivia-view.

When the page is initally loaded, a call is made to fetchCategories. Finish this function skeleton found in trivia.js to fetch from your trivia.php to get the JSON response of all categories available (mode=categories). Use the provided populateCategories function upon a successful response in this fetch request.

Exercise 4 Part II: Showing Questions and Answers

Next, when a user clicks the "New Question" button, a call to showTrivia is made from toggleQA. Finish this showTrivia function to make a request to trivia.php every time it is called. Your trivia.php should send back data for a trivia tidbit if implemented correctly in Exercise 3. Upon success, you can use the provided displayQuestion function to show the new question data.

Exercise 5: Adding a POST Request (1/2)

Now, we'll get some more practice handlng a POST request from our PHP service. Recall that while GET requests are often used to "get" information from a web service, POST requests are often supported by web services to take a request from a client and update some information on the server (e.g. adding to .txt files).

We'll add support to our trivia.php web service to allow a client to add a new question/answer entry to an existing category!

Exercise 5: Adding a POST Request (2/2)

Add a check to your PHP such that if no GET parameter of mode is passed, three required POST parameters are checked:

  • category - name of category to add new q/a entry to
  • question - new question to add for category
  • answer - answer text for new question

If any of these parameters are missing or the passed category does not correspond to a category folder, output a helpful 400 error message of your choice. Otherwise, write the necessary code to create a new text file (following naming conventions of the others) with the following format:

Q: <new-question>
A: <new-answer>

contents of new text file

Upon success, your web service should print the following plaintext response:

New entry added for <category> category!

plaintext response for POST request

Exercise 6: Back to JS: Fetching with a POST Request

Now that you've implemented POST request handling in your PHP, add features to make a POST request in trivia.js when a the "Submit Entry!" button is clicked in the "Add Trivia" view. Make sure to display a helpful message in the #response paragraph if missing question text in the textarea and a corresponding answer in the answer input box.

Adding entry

Solution

Runnable solution

JS (source)

PHP (source)