CS637 Programming Project 2

Pizza2: using and implementing Web Services

First Delivery (10 points, counted as a homework)
Due  Monday midnight, Dec. 7, in your /var/www/html/cs637/username directory on pe07, in subdirectories pizza2_server, pizza2_phpclient, and pizza1. (everything except pizza2_jsclient).

Final Delivery (25 points)
Due Sunday midnight, Dec. 13, in your /var/www/html/cs637/username directory on pe07, in subdirectories pizza2_server, pizza2_phpclient, pizza2_jsclient, and pizza1.

Students may work in pairs for this project if neither partner was involved in copying in the first project. Put a README in both top-level server project directory (/cs637/username/pizza2_server) stating both names and usernames, and whether this directory should be graded or the partner's. A partnership should provide a good README to go with the project, with a line of text on each modified file.

The purpose of this project is to show how web services can be used to centralize data management at one host on the Internet, the server, which answers web service requests for its data.  This one server can support potentially many client systems which use web services to the server to access the shared data. In our case the server could serve many individual pizza shops in dormitories spread out on one campus. In fact, we would have to add shop ids to our data to make this work.

The functionality of our pizza1 project will be split into two parts, the student app and the admin app. We will continue to use pizza1 for its admin functionality, but re-implement the student app using web services. The client side written in PHP, using the web services, will be supplied, and you will write the PHP server side, answering the web service requests. Then you will rewrite the client in Javascript, without JQuery. Thus the final submission will have four projects, two of which you have written:

/cs637/username/pizza1 (provided, used for admin UI only, runs on DB/web server)

/cs637/username/pizza2_phpclient (provided, implements student UI, runs on any PHP/web server)

/cs637/username/pizza2_server (you write this as a Slim server, following the form of ch05_gs_server, runs on DB/web server)

/cs637/username/pizza2_jsclient (you write this to implement student UI, runs in user's browser)

Web services for Pizza2 student actions

GET /pizza2_server/api/day          returns the current day number for the system (implemented in pizza2_server_setup)

POST /pizza2_server/api/day       reinitialize database (for testing, implemented in pizza2_server_setup)

GET /pizza2_server/api/toppings/2   returns info on topping 2

GET /pizza2_server/api/toppings  returns info on all toppings

GET /pizza2_server/api/sizes  returns info on all  sizes

GET /pizza2_server/api/users  returns info on all  users

GET /pizza2_server/api/orders  returns info on all orders

GET /pizza2_server/api/orders/{id}  returns info on order of id (id)

POST /pizza2_server/api/orders    adds an order

PUT /pizza2_server/api/orders/{id}    updates an order (so user can acknowledge receipt)

Note: Here "/pizza2_server/" will actually be /cs637/username/pizza2_server/.

Representations:

Day:  simple text number, (int converted to JSON)

Topping, Size, User, Order: PHP data structures converted to JSON:

Web Service client requests from PHP (code supplied in pizza2_phpclient)

The needed GET and POST requests from pizza2_phpclient could be done using the curl library that comes with PHP, but it is quite difficult, especially to recover the Location header of the response when a new resource is created. This Location header contains the newly assigned URL, which itself contains the new id of the resource. Luckily we can use the Guzzle PHP Component to greatly simplify this programming. The library code for Guzzle is provided in the vendor directory of the project. Like all proper PHP Components, the various classes of the component can be autoloaded, and all we need to do is include the provided autoloader.php. Note that this works even though our own code is not object-oriented.

Web Service server-side request handling using PHP

We will use Slim to organize and implement the server-side request handling. Study the provided example ch05_gs_server to see how it works, and implement pizza2_server in the same style. The Slim component is provided in the provided skeleton project pizza2_server_setup.

Testing the server using Curl (the program, not the library)

The web services can be tested independently of PHP by command-line curl. For example, to find out the current day for the server, as explored in homework 4

The GETs can also be done by a browser: just browse to the above URL and look for a single number as its response.There will be Linux/Mac and Windows shell programs using curl provided for testing in the proj2_tests directory. Curl is available on Mac, Linux, and recently-installed Windows 10. In case you have an older Windows system, note that it is somewhat difficult to install curl on Windows, so consider early deliveries and testing on pe07. The final grading-run testing will involve such curl commands, as well as Selenium tests of the pizza2 UI provided in your Javascript client.

Note that the three projects are installed as subdirectories of the top-level username directory. It's important to keep them this way so that the client can easily find the server.  Just unzip the zipfiles to XAMPP's  htdocs/cs637/username/.

Changes to pizza1 to create pizza2/pizza2_phpclient

Important files for server-side development

pizza2_server/database/createdb.sql, dropdb.sql as in pizza1. However dev_setup.sql has been changed to give pizza_user ALTER privilege, so you need to rerun it, then use createdb.sql, to reinitialize the system.

pizza2_server/api/index.php: implement the server-side web services with help of Slim. See ch05_gs_server/index.php for a model.

pizza2_server/api/.htaccess:  needed to get the Apache web server to execute index.php for any incoming URL .../rest/... (no edits needed)

pizza2_server/vendor  holds Slim component code. Netbeans finds errors in the a module of this code and puts a red mark on the vendor directory and its ancestors in the project, but this doesn't affect our use of the code.

Getting Started with server-side development

Unzip the supplied project zip files to XAMPP's htdocs/cs637/username/, creating two subdirectories there named pizza2_phpclient and and pizza2_server, alongside ch05_gs_client and ch05_gs_server. Also make sure that there is a working pizza1 project there too.

Set up a project in Netbeans for pizza2_phpclient and another for pizza2_server.  The easiest way is just to create each project in htdocs/cs637/username/pizza2_phpclient and htdocs/cs637/username/pizza2_server. Change api/index.php to use your username in the server project (the client doesn't use the database directly), and view/header.php in the client project. Also see pizza2_phpclient/README and pizza2_server/README for more info.

The pizza database is unchanged, but the pizza_user on your development system needs ALTER privs, so you need to re-execute dev_setup.sql and recreate the database (createdb.sql), or alternatively execute the appropriate grant command to give pizza_user alter privilege on the tables in pizzadb.  If you leave it as is, some of the proj2_tests will fail because the order ids will not be reinitialized (back to 1) when the database is reinitialized by POST of 0 to /day. This special reinit is only needed on your development system. Your pe07 mysql user has many more privileges.

Note: Don't try to run pizza2_server/api/index.php by using Run in Netbeans or by browsing to it: it only works as a web service handler.

You can use a browser to generate GETs to REST URLs. Try browsing to .../pizza2_server/api/day to see the server's current day. This should work using the provided pizza2_server_setup code.

Once the day service is seen working, start on on making the topping web services work properly. Then toppings should show up on the student welcome page of pizza2_phpclient. Also start using the proj2_tests to test the web services directly. See its README and the usage information at the start of the files. First test, on pe07: "servertest1.sh eoneil1" to run against the supplied project deployed as "student" user eoneil1 on pe07 (which is localhost when we're logged in on pe07). On a home Windows system, use "servertest1 username" where username is your own pe07 username. On a Mac or Linux, use "servertest1.sh username" after using "chmod +x *.sh" to make them executable.

pizza2_jsclient: the Javascript client for our API
Client-side development in Javascript can start as soon as you understand the basics of Javascript, that is, when you understand Chap. 4 of Purewal. (Note you don't need to read Chapters 1 through 3 first if you understand HTML and CSS well.) The examples there (most of which use JQuery) will be available in plain Javascript as well, and the main example, Amazeriffic, in the two versions, with and without JQuery. Please use the version without JQuery as your go-to example.

Like Amazeriffic, the JS app should be a single-page app (SPA). The user first sees the student welcome screen with the pizzapie.jpg image, much like the student welcome page of pizza1. The user then selects their username from a list of names. When a user wants to order a pizza, a form shows up for this purpose, and disappears again when the order is submitted. The status of pizza orders for the user is displayed instead, with a way for the user to refresh this report (without refreshing the whole page), and of course to order another pizza.

Following Amazeriffic, the multiplexing of the single page can be done by using two tabs, one for welcome and status and the other for ordering a pizza. But this is not required: you can come up with other arrangements as long as the pizza order form only shows for the order-pizza action. You don't need to offer a means to change the username on the order form, just in the welcome/status view.

The provided setup project starts up with both tab contents showing on the screen, student welcome on top, order form below, because there is no tab control code yet. You can get most of the credit by making this work without the tab control, so do that tricky part last. The setup has the needed HTML and CSS, so you just add the Javascript, without JQuery. Note that comments in app.js give pseudocode for needed code and indicate a suggested sequence of implementation steps to guide your develoment.

Source Files (set up in provided project, but keep it this way)
Please follow Amazeriffic's directory/file setup:
javascripts/app.js
stylesheets/main.css
images/pizzapie.jpg
index.html

Implementation Notes for the JS Client

Running the JS App
The JS app (pizza2_jsclient) uses web service requests to the PHP Slim server of the pizza2_server project to access the pizzadb in mysql and support the needed webservices. The Slim server depends on the Apache webserver's URL-rewriting capability (using file .htaccess in directory api), so we can't use the Netbeans internal server on its port 8383 for the server. Thus if you want to run your app from Netbeans, you need to make sure the baseUrl in use in app.js specifies port 80 on localhost for the server, i.e. Apache of XAMPP or Apache on pe07. In particular, a relative URL for the server won't work because it would have port 8383. With the "client" side running on port 8383 (and serving the HTML and JS to the browser) and the REST server on port 80, and requests coming from the browser, this counts as cross-origin resource sharing (CORS), so it matters that our Slim server supports that kind of access.

Browser getting data from two servers here:
browser ------------pizza2_jsclient for HTML, JS code (during page load)
              \-----------pizza2_server  REST server for API calls

The following assumes you already have a pizza2_server installed, and the mysql database loaded for it.

To execute this app under Netbeans (with a baseUrl of port 80 on localhost for web services)
  1. Make sure xampp is running Apache and mysql, for the server side
  2. Run index.html from Netbeans

To execute this app purely on XAMPP:

  1. If necessary, copy the pizza2_jsclient source to /cs637/username/pizza_jsclient under htdocs
  2. Make sure xampp is running Apache and mysql
  3. Browse to index.html, URL localhost/cs637/username/pizza2_jsclient
To execute this app on pe07 (already having a working pizza2_server):
  1. Transfer the pizza2_jsclient source to username/pizza2_jsclient under /var/www/html
  2. Browse to index.html there using http://localhost:8000/cs637/username/pizza2_jsclient, using your tunnel to pe07's port 80.
  3. But this will use the local server, not pe07, for the API (because the JS is running in the browser on the local system when it does the request). To use pe07s pizza2_server, edit the baseUrl in app.js  to replace localhost with localhost:8000 to use the tunnel to pe07's port 80 for the API. Please leave it this way for delivery.
Deliveries
First Delivery (10 points, like a homework)
Due Monday midnight, Dec. 7, in your /var/www/html/cs637/username directory on pe07, in subdirectories pizza2_server, pizza2_phpclient, and pizza1. (everything except pizza2_jsclient).

Final Delivery (25 points)
Due Sunday midnight, Dec. 13, in your /var/www/html/cs637/username directory on pe07, in subdirectories pizza2_server, pizza2_phpclient, pizza2_jsclient, and pizza1.
Remaining late days can be used, up to two days. Partners can combine remaining late days up to the max of two.