Home > 2010 Fall DPS907 > Building the web service for your programming assignment

Building the web service for your programming assignment

November 24, 2010 Leave a comment Go to comments

This post details the design and operation of your professor’s example web service for the programming assignment’s “Option 4”.

While this post covers the process of coding the web service for the programming assignment’s “Option 4”, it will also be valuable if your assignment covers a different option. Use the section headings below to guide you, and substitute your data model and web service goals when reading the narrative.

In your assignment, no matter what option you select, it is expected that you will end up coding approximately thirty (30) or more URI templates / methods.

.

SQL Server and LINQ help information

Use the similarly-named section in the previous post (“Database for the web services programming assignment”) to help you understand the database, and/or to help you create your own design.

.

Examine the professor’s sample web service

Your professor has created an example web service, and it is located at this URI:

http://warp.senecac.on.ca/wsa500_103a03/ws/

Append “help” to the web service URI, and you will see 54 URI templates, and a brief description of what each delivers. At the present time, all of these implement the HTTP GET method.

.

Create the Entity Framework data model

The first task for any data-backed web service is to create the Entity Framework (EF) data model. You have done this many times before, so the process will be familiar to you.

What happens if the database structure changes? Open the data model. Right-click an empty area of the design surface. Notice the ” re-generate ” option. Select it, and the EF data model is updated.

.

Easy task – creating the return-all and return-one methods

When you briefly look at the data model for the School of Computer Studies database, you will see about eleven (11) entities. One of those is an entity for the “ProgramCourse” junction table. It appears in the data model, because the database junction table includes a column that doesn’t appear in either the Program or Course entities.

Notice also that the other database junction table doesn’t have an entity. This is because the database junction table included only foreign keys that pointed back to the Employee and JobDuty tables. Entity Framework supports many-to-many relationships easily.

So, in summary, the model has ten (10) entities. Therefore, your task is to create URI templates, and the methods, which will return entity objects. Logically, you need a URI template that returns all of the entity objects, as a collection. Additionally, you need a URI template that returns a specific entity object, identified by its <entityname>ID property. Completing this task will yield twenty (20) URI templates / methods.

Obviously, the method return types will be List<entityname> for the collection, and <entityname> for the object. When returning the collection, you can decide whether to sort (“orderby”, with an optional “descending” modifier) the results.

.

Next – study your data model, and anticipate how it will be used

Now it’s time to study your data model in more depth. This process will reveal the need for more URI templates / methods.

It is very important to know and understand your data, and its meaning. When you study the data model, and anticipate how consumers can use the web service, you will easily discover the need for many more URI templates / methods. Some of these ideas are covered in the following sections.

.

Begin coding methods that deliver value to the consumer

When you studied the data model, you noticed that every entity had an <entityname>ID property (e.g. ProgramID, CourseID). The corresponding SQL Server database columns are the primary keys, of type int, and they’re configured as auto-incrementing values.

For some queries, this “ID” property doesn’t carry much meaning or utility. For other queries, doing a lookup by an auto-generated ID value doesn’t make much sense.

Therefore, a good first place to start is to look at each entity, and think about one or more “natural” ways to query for an object, or a collection of objects. For example, if you’re interested in a specific course, it’s more natural to make a query that includes its course code, or course name. In summary, just ask yourself how you would like to query and consume the data – that will help you create URI templates / methods.

After going through the 10 entities, you will conclude that it is very easy to create another 10, 20, 30, or more URI templates that implement these ideas.

.

An interesting query situation – employees

Many entities are easy to identify in a unique way. For example, a specific course (e.g. IPC144) is known uniquely as “IPC144” or “Introduction to Programming Using C”. This fact and observation makes it reasonably easy to contemplate and then design URI templates / methods that enable easy and logical querying.

Employees are somewhat different. Why? Its possible and common that two or more people share the same first name or last name. In the School of Computer Studies, the first name + last name combination is typically unique, so you can build upon that.

In your professor’s example web service, a few URI templates / methods were created to support the querying of employees by using all or part of their names:

  1. Number of employees who match the supplied last name
  2. A collection of employees who match all or part of the supplied last name
  3. The first employee that matches all or part of the supplied last name and first name

.

If you look at these method descriptions, you will see that they meet different needs.

Consider a consumer, who wants to query for a specific professor. The consumer knows only the professor’s last name and first name. The first step may be to ask for the number of employees who match the supplied last name of the professor (query #1 above, which uses the Count() method). If the return value is “1”, that means that a unique match was found. A second query (#3 above) could then as for the first (and only) employee that matches all or part of the supplied last name and first name.

However, what if query #1 above returns a value more than “1”? The use case is slightly different, but not all that different. The bottom line is that you must know your data, and anticipate how the data will be used.

The following is an example of a query (for #2 above) that enables the consumer to call a URI with all or part of a professor’s last name. The return value will be a collection of zero or more objects:

.

Coding LINQ queries that have multiple “where” components

Continuing the employee theme above, how do we use LINQ to code the third query? We need two “where” components. Check the example, shown below:

.

Handling a many-to-many relationship – programs and courses

Now it’s time to learn a bit about coding a query for a many-to-many relationship.

A program can have many courses – we know that.

We also know that a course can be a part of many programs.

Our EF data model has entities for Program and Course, and an entity for the junction table, ProgramCourse:

Let’s attempt to answer this question: What programs include the IPC144 course?

First, we must return a collection of Program objects. That will be the method’s return type.

Next, we must accept a “course” argument. For the example method shown below, we will accept a CourseID value. Your method, in your programming assignment, may work the same way, or it may accept a course code (or some other) argument.

Then, decide what the focus of the query must be. In a model that includes a junction table, this junction table is the target of our query.

So, we ask for an object set where the course ID matches the supplied course ID value. Then, we use the entity’s “Program” navigation property effectively select the program object for each item in the object set. Check out the sample code below. Notice the “as Program” clause in the “select” component – it enables you to assert that you want the query type to be “Program”.

Now, you should be ready to code the answer to this question: What courses are in the BSD program?

.

Handling a many-to-many relationship – employees and job duties

The previous section taught you how to code a query on entities that have many-to-many relationship, where there is a junction table. In this example, we consider the situation where there is no junction table. Examine the EF data model, and look at the Employee entity:

An employee can have zero or more additional “job duties” – these are job duties over and above those included in the job title idea.

Also, a job duty can be assigned to zero or more employees.

So, how do we answer the question: What employees have been assigned a specific job duty?

Well, there’s no junction table. So, we examine the EF data model. The Employee entity has a “JobDuties” navigation property. This means that the JobDuties property is a collection of JobDuty objects.

Looking at the JobDuty entity, we see that it has an “Employees” navigation property. This means that the Employees property is a collection of Employee objects.

We can begin our query by focusing on either entity, but let’s start with the Employee entity, because that’s what we want for our result set – a collection of employees who have been assigned a specific job duty.

First, we query the employees; its object set is represented in the code example below by the e variable.

Then, we query again. Notice the second “from” component. We look at the JobDuties property in every employee, and look for a JobDutyID match. See the code sample below.

At this point in time, you should be prepared to code any methods that you need.

.

Custom data model class, to shape the results

The database tables were designed so that each one included an “ID” column, for an auto-generated key. This may or may not be “real world”, but it enabled me to introduce a fairly simple and understandable abstraction. This feature will prepare you to use more complex models in the future.

One of the “problems” with this approach is that some of the web service methods return results that cannot be immediately understood, or displayed in a user interface. Consider and study the CourseInstanceSession entity. It is designed to return:

  • Course instance ID value
  • Room ID value
  • some other data that’s immediately usable

.

The course instance ID property, and the CourseInstance navigation property, references a specific “course instance” – an offering of a course in a semester. A standard query of the course instance entity itself is designed to return:

  • Course ID value
  • Semester ID value
  • Employee ID value (i.e. the course’s professor)
  • some other data that’s immediately usable

.

We can easily make a URI template / method that returns a collection of course instance sessions for a specific course instance – see the URI template “/courseinstance/timetable/{courseinstanceID}/raw”. Here’s an example of what it returns:

As you can see, the results are good and meaningful, but they may not be ideal for the consumer. Think of how the results could be used. You may want to improve these results by doing the “decoding” before sending them out. For example, you can convert a “course instance ID” value into a course code, section letter identifier, and semester.

To do this, you can create a “custom class” to model the data that you want to return. You have already studied the POCO classes that were generated for your EF data model, so you know that they’re simple classes, with simple properties. Our custom class can be as simple.

Here’s how to get started:

  1. In Visual Studio, add a new item, a Visual C# “Code File”; give it a name similar to “CustomEntities.cs”
  2. Enter a namespace declaration; the namespace is the same as your project’s namespace
  3. Add a class for each custom entity that you intend to deliver

.

Remember, in Visual Studio, you can quickly enter properties by using this technique:

  1. At the beginning of a line of code, type “prop”, and press tab, and tab again
  2. The editor will expand this into a property declaration syntax
  3. Enter your property’s type, and its name

.

In your professor’s example web service, it was decided that a friendlier version of the above was needed. Here is the C# class source code file that describes the “CECourseSessions” custom entity:

Now that we have this model object defined, we can return it, as an object, or as a collection of objects. Therefore, let’s modify the standard URI template / method, which anyone can write, and use the custom entity to “shape” the results into something more friendly and usable.

We begin the query in the usual way, by selecting from CourseInstanceSessions, with the proper “where” component.

Then, in the “select” component, we “shape” the query:

  • for each matching CourseInstanceSession result, we create a new instance of our custom entity, CECourseSession
  • we configure each property of a CECourseSession with the value from the original query
  • when we need a property from a related entity, we use standard dot-separated syntax to reference the property, via one or more navigation properties

.

In the code sample below, the variable “c” represents the set of matching CourseInstanceSession results. For each “c”, walk the object graph to get the data you want; e.g. c.CourseInstance.Course.CourseCode will return the (string) course code.

The results of the query are shown below. Much friendlier, and easier to use (sometimes!).

.

Summary

In this post, you learned how to approach the job of creating a non-trivial, and significantly-sized web service. We covered coding techniques for methods that expose URIs that are useful to consumers. Along the way, you learned how to study a data model, and anticipate the usage of the data, to design and implement a set of web service URI templates / methods.

.


Advertisements
Categories: 2010 Fall DPS907
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: