In this course, a final programming project will take the place of formal exams to test your understanding of the material. The final project will involve working with a team of 3-4 people to implement a complete RESTful API for an application called Tarpaulin. You can find more details about Tarpaulin below. The API you implement will need to utilize most the components of a modern API that we talked about in class.
The application for which you'll write an API for this project is Tarpaulin, a lightweight course management tool that's an "alternative" to Canvas. In particular, Tarpaulin allows users (instructors and students) to see information about the courses they're teaching/taking. It allows instructors to create assignments for their courses, and it allows students to submit solutions to those assignments.
The Tarpaulin API you implement must support all of the endpoints described in the Tarpaulin OpenAPI specification. Importantly, you are free to implement the endpoints described in the OpenAPI specification however you see fit. For example, you may use whatever database you want, and you may design your API architecture to meet your own needs.
The OpenAPI specification linked above will provide most of the details of the API you'll implement, but some more details are included below.
There are several kinds of entity the Tarpaulin API will need to keep track of:
Users — these represent Tarpaulin application users. Each User can have one of three roles: admin, instructor, and student. Each of these roles represents a different set of permissions to perform certain API actions. The permissions associated with these roles are defined further in the Tarpaulin OpenAPI specification.
Courses — these represent courses being managed in Tarpaulin. Each Course has basic information, such as subject code, number, title, instructor, etc. Each Course also has a list of enrolled students (i.e. Tarpaulin Users with the student role) as well as a set of assignments. More details about how to manage these pieces of data are included both below and in the Tarpaulin OpenAPI specification.
Assignments — these represent a single assignment for a Tarpaulin Course. Each Assignment has basic information such as a title, due date, etc. It also has a list of individual student submissions.
Submissions — these represent a single student submission for an Assignment in Tarpaulin. Each submission is tied to the student who submitted it and marked with a submission timestamp. Each submission is associated with a specific file, which will be uploaded to the Tarpaulin API and stored, so it can be downloaded later.
Many of the actions that can be performed with the Tarpaulin API are similar to ones we've seen in the work we've done in class, including fetching entity data and creating, modifying, and deleting entities. These actions should not need much explanation beyond what's included in the Tarpaulin OpenAPI specification. A few specific actions deserve more attention, though:
Course roster download — this action, implemented by the GET /courses/{id}/roster endpoint, allows certain authorized users to download a CSV-formatted roster for a specific course. The roster will contain a list of the students currently enrolled in the course, in CSV format, e.g.:
"abc123","Jane Doe","doej@oregonstate.edu" "def456","Luke Skywalker","skywallu@oregonstate.edu" ... Importantly, this file must be generated by the API, based on the list of enrolled students stored in the database. There are several alternative ways this can be accomplished. For example, each time the roster is requested, it can be generated on the fly based on appropriate database queries before being sent back to the client. Alternatively, the roster could be pre-generated automatically whenever an update is made to a course's enrollment, and requests for the roster can simply send back this pre-generated file.
Assignment submission creation — this action, implemented by the POST /assignments/{id}/submissions endpoint, allows authorized student Users to upload a file submission for a specific assignment. Importantly, the file uploaded for each Submission must be stored by the API in such a way that it can be later downloaded via URL. Specifically, when storing the submission file, the API should generate the URL with which that file can later be accessed. This URL will be returned along with the rest of the information about the Submission from the GET /assignments/{id}/submissions endpoint.
User data fetching — this action, implemented by the GET /users/{id} endpoint, allows Users to see their own data. Importantly, only a logged-in User can see their own data. The data returned by this endpoint should also include the list of classes the User is enrolled in (for student Users) or teaching (for instructor Users).
Course information fetching — this action, implemented by the GET /courses and GET /courses/{id} endpoints, allows users to see information about all Courses or about a specific Course. Note that the information included by both of these endpoints should not return information about a Course's enrolled students or its Assignments. Instead, that information can be fetched by the GET /courses/{id}/students and GET /courses/{id}/assignments endpoints, respectively.
A few of the Tarpaulin API endpoints must be paginated:
GET /courses GET /assignments/{id}/submissions It's up to you to determine the appropriate way to paginate these endpoints, including how the page size is set, etc.
Many of the endpoints in the Tarpaulin API require authorization, as described in the Tarpaulin OpenAPI specification. You may implement this using the standard JWT-based authorization scheme we discussed in class.
Your API application should have a complete Docker specification that allows it to be launched from scratch on a new machine using Docker Compose. This specification will likely include both a Dockerfile, in which the dependencies for your main API server are specified, and a Docker Compose specification, in which each service in your API (e.g. database, etc.) is specified and tied to the other API services. Importantly, this specification should allow your API to be launched from scratch. Thus, it must include any necessary database initialization, etc. required by your API.
In addition to the requirements listed above, your API must implement:
New tech, 3rd-party libraries, and other tools You may treat the final project as an opportunity to learn how to use API backend technologies we didn't cover in class. Specifically, if there's a database implementation, third-party tool or library, etc. you want to use for the project, feel free to do so.
The code for your final project must be in a GitHub repository.
The repository created for your team will be public by default, and I encourage you to keep it public. These final projects should be nice demonstrations of your web development abilities and will be a good item to have in your CS portfolio. It will be great to have the code in a public GitHub repo so you can share it easily when you want to. However, you will have full administrative control over the repository that's created for your project, which means you'll be able to make it private if you wish.
When working with a team on a shared GitHub repo, it's a good idea to use a workflow that uses branches and pull requests. This has a few advantages:
By not working within the same branch, you can better avoid causing conflicts, which can occur when you and another member of your team edit the same parts of the code at the same time.
It helps you to be more familiar with the entire code base, even the parts that other team members are working on, because you'll see all of the changes to the code as you review pull requests. This can help you develop more rapidly because you won't have to spend as much time understanding code that others have written.
It helps to ensure high quality code. Code in pull requests is not incorporated into the master code branch until the code request is reviewed and approved. That means everyone has a chance to improve pull request code before it becomes permanent.
One simple but effective branch- and pull-request-based workflow you might consider is the GitHub flowLinks to an external site..
If you don't have a final project team, please post on Discord in the class channel and build a team!
This is required to receive credit for this project.
To get a grade for your project, your team must do a brief (5-15 minute) demonstration video of your project's functionality using cURL, Postman, or your web browser where appropriate.
Each member of the team must participate; it's recommended you demo the portions of the project you worked on.
Submit the video link to Canvas.
This video doesn't need to be professional grade; just recording a screenshare in Zoom is fine, and don't worry about editing.
Be sure to submit the following for the team:
Github repo link Video link And each individual needs to submit:
Their own Team Evaluation (see below). This evaluation will not be shared with any other team members. Grading criteria Your team's grade (out of 100 points) for the final project will be based on successfully implementing a complete API that satisfies these criteria:
50 points — Your API successfully implements all of the endpoints described in the Tarpaulin OpenAPI specification. 10 points — Your API endpoints correctly require authorization, as described in the Tarpaulin OpenAPI specification. 5 points — Your API correctly paginates the appropriate endpoints, as described above and in the Tarpaulin OpenAPI specification. 10 points — Your API has a complete Docker specification and can be launched from scratch using Docker Compose, as described above. 5 points — Your API implements one of the features described under "additional requirements" above. 20 points — Your API has a high-quality design and implementation. Remember also, if your team does not do a video demo for your project, you will not receive credit for the project!
Your individual grade for the project will be based on your team's grade and also on evidence of your meaningful participation in your team's work on the project, including from these sources:
The commit log of your GitHub repository. Your presence at and participation in your team's project video demo. A team evaluation completed by each member of your project teamLinks to an external site.. ("Make a Copy" of this document to submit.) In particular, if your GitHub commit log shows that you did not make meaningful contributions to your team's implementation of your app, if you do not participate in your team's demonstration of your app (without explicit prior approval by me), or if your project teammates submit team evaluations in which they agrees that you did not do an appropriate share of the work on your final project, you will receive a lower grade on the project than your teammates. I may use other sources as evidence of your participation, as well.