COMSCI 335 / 2018 / v1 Page 1 of 8 radu&james
Introduction
Assignment #4R: OData REST services
This assignment requires you to create two OData REST services that accept GET requests, in order to retrieve data from two XML “table” documents: XOrders.xml and XCustomers.xml, in ATOM+XML or JSON formats.
These XML documents are trimmed (and slightly modified) versions of the similarly named tables – Orders and Customers – from the public and well-known Northwind SQL database sample.
The service must be written in two versions, written (1) in C# and (2) in F#, starting with the provided skeletons. These two projects will be compiled with their command-line compliers, CSC and FSC, respectively, via given batch files. The services will tested by running IISExpress via another given batch file (we’ll typically run this on port 8181, which is available in the labs). The marking will be performed by scripts, so exact matches are essential.
Server data
Our XML documents are not schema based. Therefore, let’s also have a look the original SQL types, as Linqpad sees these. This will allow us to properly identify the types.
Note the several Orders properties that are nullable (?) – We keep three of these (see below)!
Note the following primary keys: OrderID for Orders and CustomerID for Customers. Note also the foreign key CustomerID in Orders. Together, these define the following “duck’s paw” one-to-many and many-to-one relationships:
o Customer:fromOrderstoCustomers o Orders:fromCustomerstoOrders
COMSCI 335 / 2018 / v1 Page 2 of 8 radu&james Our XML documents keep only part of the actual SQL columns
o XOrderskeeps,inorder:OrderID,CustomerID,OrderDate,ShippedDate,Freight, ShipName, ShipCity, and ShipCountry – also EmployeeID, but this will be ignored.
o XCustomerskeeps,inorder:CustomerID,CompanyName,andContactName.
o The“ducks’paw”relationshipsmustberebuiltbytheprogram. Here follow the first few lines of each of our XML documents: XCategories
<Customers> <Customer>
<CustomerID>ALFKI</CustomerID> <CompanyName>Alfreds Futterkiste</CompanyName> <ContactName>Maria Anders</ContactName>
</Customer>
… >
XOrders
<Orders> <Order>
<OrderID>10248</OrderID> <CustomerID>VINET</CustomerID> <EmployeeID>5</EmployeeID> <OrderDate>1996-07-04T00:00:00</OrderDate> <ShippedDate>1996-07-16T00:00:00</ShippedDate> <Freight>32.3800</Freight>
<ShipName>Vins et alcools Chevalier</ShipName> <ShipCity>Reims</ShipCity> <ShipCountry>France</ShipCountry>
</Order>
… >
<!—ignore this –>
The three nullable properties may appear in three different ways, e.g.:
<Freight />
<Freight> </Freight>
<!– <Freight>32.3800</Freight> –>
COMSCI 335 / 2018 / v1 Page 3 of 8 radu&james
Sample GET URL queries and expected results for C# (for F# replace A4CS => A4FS); slightly reformatted (added readability spaces), and assuming the service is listening on port 8081.
odata_xml_0
http://localhost:8181/A4CS.svc/?$format=json
odata_xml_1
http://localhost:8181/A4CS.svc/Orders()?$format=json&$top=0&$inlinecount=allpages
odata_xml_2
http://localhost:8181/A4CS.svc/Customers()?$format=json&$orderby=CustomerID&$top=3&$select =CustomerID,ContactName,CompanyName
odata_xml_3
http://localhost:8181/A4CS.svc/Orders()?$format=json&$orderby=OrderID desc&$top=3&$select=OrderID,CustomerID,ShipName,ShipCity,ShipCountry
{“odata.metadata”:”http://localhost:8181/A4CS.svc/$metadata”,”value”:[ {“name”:”Customers”,”url”:”Customers”}, {“name”:”Orders”,”url”:”Orders”}]}
{“odata.metadata”:”http://localhost:8181/A4CS.svc/$metadata#Orders”,”odata.count”:”830″, “value”:[]}
{“odata.metadata”:”http://localhost:8181/A4CS.svc/$metadata#Customers& $select=CustomerID,ContactName,CompanyName”,”value”:[ {“CustomerID”:”ALFKI”,”CompanyName”:”Alfreds Futterkiste”, “ContactName”:”Maria Anders”}, {“CustomerID”:”ANATR”,”CompanyName”:”Ana Trujillo Emparedados y helados”, “ContactName”:”Ana Trujillo”}, {“CustomerID”:”ANTON”,”CompanyName”:”Antonio Moreno Taquer\u00eda”, “ContactName”:”Antonio Moreno”}]}
{“odata.metadata”:”http://localhost:8181/A4CS.svc/$metadata#Orders& $select=OrderID,CustomerID,ShipName,ShipCity,ShipCountry”,”value”:[ {“OrderID”:11077,”CustomerID”:”RATTC”,”ShipName”:”Rattlesnake Canyon Grocery”, “ShipCity”:”Albuquerque”,”ShipCountry”:”USA”}, {“OrderID”:11076,”CustomerID”:”BONAP”,”ShipName”:”Bon app'”, “ShipCity”:”Marseille”,”ShipCountry”:”France”}, {“OrderID”:11075,”CustomerID”:”RICSU”,”ShipName”:”Richter Supermarkt”, “ShipCity”:”Gen\u00e8ve”,”ShipCountry”:”Switzerland”}]}
COMSCI 335 / 2018 / v1 Page 4 of 8 radu&james
odata_xml_4
http://localhost:8181/A4CS.svc/Orders()?$format=json&$orderby=OrderID&$filter=OrderDate eq null&$expand=Customer&$select=OrderID,CustomerID,OrderDate,ShippedDate,Freight
odata_xml_5
http://localhost:8181/A4CS.svc/Orders()?$format=json&$orderby=OrderID&$filter=ShippedDate eq null&$expand=Customer&$select=OrderID,CustomerID,OrderDate,ShippedDate,Freight
{“odata.metadata”:”http://localhost:8181/A4CS.svc/$metadata#Orders& $select=OrderID,CustomerID,OrderDate,ShippedDate,Freight”,”value”:[ {“OrderID”:10249,”CustomerID”:”TOMSP”,”OrderDate”:null, “ShippedDate”:”1996-07-10T00:00:00″,”Freight”:”11.6100″}, {“OrderID”:10250,”CustomerID”:”HANAR”,”OrderDate”:null, “ShippedDate”:”1996-07-12T00:00:00″,”Freight”:”65.8300″}]}
{“odata.metadata”:”http://localhost:8181/A4CS.svc/$metadata#Orders& $select=OrderID,CustomerID,OrderDate,ShippedDate,Freight”,”value”:[ {“OrderID”:11008,”CustomerID”:”ERNSH”,”OrderDate”:”1998-04-08T00:00:00″, “ShippedDate”:null,”Freight”:”79.4600″}, {“OrderID”:11009,”CustomerID”:”GODOS”,”OrderDate”:”1998-04-08T00:00:00″, “ShippedDate”:null,”Freight”:”59.1100″}, {“OrderID”:11010,”CustomerID”:”REGGC”,”OrderDate”:”1998-04-09T00:00:00″, “ShippedDate”:null,”Freight”:”28.7100″}, {“OrderID”:11019,”CustomerID”:”RANCH”,”OrderDate”:”1998-04-13T00:00:00″, “ShippedDate”:null,”Freight”:”3.1700″}, {“OrderID”:11039,”CustomerID”:”LINOD”,”OrderDate”:”1998-04-21T00:00:00″, “ShippedDate”:null,”Freight”:”65.0000″}, {“OrderID”:11040,”CustomerID”:”GREAL”,”OrderDate”:”1998-04- 22T00:00:00″,”ShippedDate”:null,”Freight”:”18.8400″}, {“OrderID”:11045,”CustomerID”:”BOTTM”,”OrderDate”:”1998-04-23T00:00:00″, “ShippedDate”:null,”Freight”:”70.5800″}, {“OrderID”:11051,”CustomerID”:”LAMAI”,”OrderDate”:”1998-04-27T00:00:00″, “ShippedDate”:null,”Freight”:”2.7900″}, {“OrderID”:11054,”CustomerID”:”CACTU”,”OrderDate”:”1998-04-28T00:00:00″, “ShippedDate”:null,”Freight”:”0.3300″}, {“OrderID”:11058,”CustomerID”:”BLAUS”,”OrderDate”:”1998-04-29T00:00:00″, “ShippedDate”:null,”Freight”:”31.1400″}, {“OrderID”:11059,”CustomerID”:”RICAR”,”OrderDate”:”1998-04-29T00:00:00″, “ShippedDate”:null,”Freight”:”85.8000″}, {“OrderID”:11061,”CustomerID”:”GREAL”,”OrderDate”:”1998-04-30T00:00:00″, “ShippedDate”:null,”Freight”:”14.0100″},
COMSCI 335 / 2018 / v1 Page 5 of 8 radu&james
{“OrderID”:11062,”CustomerID”:”REGGC”,”OrderDate”:”1998-04-30T00:00:00″, “ShippedDate”:null,”Freight”:”29.9300″}, {“OrderID”:11065,”CustomerID”:”LILAS”,”OrderDate”:”1998-05-01T00:00:00″, “ShippedDate”:null,”Freight”:”12.9100″}, {“OrderID”:11068,”CustomerID”:”QUEEN”,”OrderDate”:”1998-05-04T00:00:00″, “ShippedDate”:null,”Freight”:”81.7500″}, {“OrderID”:11070,”CustomerID”:”LEHMS”,”OrderDate”:”1998-05-05T00:00:00″, “ShippedDate”:null,”Freight”:”136.0000″}, {“OrderID”:11071,”CustomerID”:”LILAS”,”OrderDate”:”1998-05-05T00:00:00″, “ShippedDate”:null,”Freight”:”0.9300″}, {“OrderID”:11072,”CustomerID”:”ERNSH”,”OrderDate”:”1998-05-05T00:00:00″, “ShippedDate”:null,”Freight”:”258.6400″}, {“OrderID”:11073,”CustomerID”:”PERIC”,”OrderDate”:”1998-05-05T00:00:00″, “ShippedDate”:null,”Freight”:”24.9500″}, {“OrderID”:11074,”CustomerID”:”SIMOB”,”OrderDate”:”1998-05-06T00:00:00″, “ShippedDate”:null,”Freight”:”18.4400″}, {“OrderID”:11075,”CustomerID”:”RICSU”,”OrderDate”:”1998-05-06T00:00:00″, “ShippedDate”:null,”Freight”:null}, {“OrderID”:11076,”CustomerID”:”BONAP”,”OrderDate”:”1998-05-06T00:00:00″, “ShippedDate”:null,”Freight”:null}, {“OrderID”:11077,”CustomerID”:”RATTC”,”OrderDate”:”1998-05-06T00:00:00″, “ShippedDate”:null,”Freight”:null}]}
odata_xml_6
http://localhost:8181/A4CS.svc/Orders()?$format=json&$orderby=OrderID&$filter=Freight eq null&$expand=Customer&$select=OrderID,CustomerID,OrderDate,ShippedDate,Freight
{“odata.metadata”:”http://localhost:8181/A4CS.svc/$metadata#Orders& $select=OrderID,CustomerID,OrderDate,ShippedDate,Freight”,”value”:[ {“OrderID”:11075,”CustomerID”:”RICSU”,”OrderDate”:”1998-05-06T00:00:00″, “ShippedDate”:null,”Freight”:null}, {“OrderID”:11076,”CustomerID”:”BONAP”,”OrderDate”:”1998-05-06T00:00:00″, “ShippedDate”:null,”Freight”:null}, {“OrderID”:11077,”CustomerID”:”RATTC”,”OrderDate”:”1998-05-06T00:00:00″, “ShippedDate”:null,”Freight”:null}]}
COMSCI 335 / 2018 / v1 Page 6 of 8 radu&james
odata_xml_7
http://localhost:8181/A4CS.svc/Customers(‘ALFKI’)?$format=json&$expand=Orders&$select=Custo merID,ContactName,CompanyName,Orders/OrderID,Orders/ShipName,Orders/ShipCity,Orders/Ship Country
{“odata.metadata”:”http://localhost:8181/A4CS.svc/$metadata#Customers/@Element& $select=CustomerID,ContactName,CompanyName, Orders/OrderID,Orders/ShipName,Orders/ShipCity,Orders/ShipCountry”,”Orders”:[ {“OrderID”:10643,”ShipName”:”Alfreds Futterkiste”,”ShipCity”:”Berlin”,”ShipCountry”:”Germany”}, {“OrderID”:10692,”ShipName”:”Alfred’s Futterkiste”,”ShipCity”:”Berlin”,”ShipCountry”:”Germany”}, {“OrderID”:10702,”ShipName”:”Alfred’s Futterkiste”,”ShipCity”:”Berlin”,”ShipCountry”:”Germany”}, {“OrderID”:10835,”ShipName”:”Alfred’s Futterkiste”,”ShipCity”:”Berlin”,”ShipCountry”:”Germany”}, {“OrderID”:10952,”ShipName”:”Alfred’s Futterkiste”,”ShipCity”:”Berlin”,”ShipCountry”:”Germany”}, {“OrderID”:11011,”ShipName”:”Alfred’s Futterkiste”,”ShipCity”:”Berlin”,”ShipCountry”:”Germany”}], “CustomerID”:”ALFKI”,”CompanyName”:”Alfreds Futterkiste”,”ContactName”:”Maria Anders”}
odata_xml_8
http://localhost:8181/A4CS.svc/Orders()?$format=json&$orderby=OrderID&$top=3&$expand=Cust omer&$select=OrderID,CustomerID,Customer/ContactName,Customer/CompanyName
{“odata.metadata”:”http://localhost:8181/A4CS.svc/$metadata#Orders& $select=OrderID,CustomerID,Customer/ContactName,Customer/CompanyName”,”value”:[ {“Customer”:{“CompanyName”:”Vins et alcools Chevalier”,
“ContactName”:”Paul Henriot *******”},”OrderID”:10248,”CustomerID”:”VINET”}, {“Customer”:{“CompanyName”:”Toms Spezialit\u00e4ten”,
“ContactName”:”Karin Josephs”},”OrderID”:10249,”CustomerID”:”TOMSP”}, {“Customer”:{“CompanyName”:”Hanari Carnes”,
“ContactName”:”Mario Pontes”},”OrderID”:10250,”CustomerID”:”HANAR”}]}
odata_xml_9
http://localhost:8181/A4CS.svc/Orders()?$format=json&$orderby=OrderID&$top=3&$expand=Cust omer&$select=OrderID,CustomerID,Customer/ContactName,Customer/CompanyName {“odata.metadata”:”http://localhost:8181/A4CS.svc/$metadata#Orders& $select=OrderID,CustomerID,Customer/ContactName,Customer/CompanyName”,”value”:[ {“Customer”:{“CompanyName”:”Vins et alcools Chevalier”,”ContactName”:”Paul Henriot *******”}, “OrderID”:10248,”CustomerID”:”VINET”},
{“Customer”:{“CompanyName”:”Toms Spezialit\u00e4ten”,”ContactName”:”Karin Josephs”}, “OrderID”:10249,”CustomerID”:”TOMSP”},
{“Customer”:{“CompanyName”:”Hanari Carnes”,”ContactName”:”Mario Pontes”}, “OrderID”:10250,”CustomerID”:”HANAR”}]}
COMSCI 335 / 2018 / v1 Page 7 of 8 radu&james
Project folder structure
Your ODATA projects should keep the given skeleton structure!
In fact, you must NOT change anything else except the jbon007 source files!
o bin:compileroutput,A4Y.dll,pluscopiesoftherequiredlibraries
o lib:requiredlibraries
o data:XMLdocuments
o _CompileA4XS.bat:compilationbatch,jbon.svc.XS=>.\bin\A4XS.dll
o _localhost-8181-A4XS.svc:URLshortcuttotestiftheserviceisrunning
o _Service_IISExpress_x64_8181.bat:startsIISExpressonport8181(64bits)
o _Service_IISExpress_x86_8181.bat:startsIISExpressonport8181(32bits)
o A4XS.svc:WCFprocessingdirective,pointingtoA4XS,A4XS(namespace,class)
o jbon007.svc.XS:sourcefile–foryoutowriteandrename(followingthedemomodel)
o Web.config:serviceconfigfile Where X is either C (for C#) or F (for F#).
Running and testing
To run and test your service, you must follow the following steps:
- Compile your source file with the given _Compile A4XS.bat; the resulting A4XS.dll will be stored in the bin folder (together will all required libraries)
- Start IISExpress with the appropriate batch
- Optionally, double click on the _localhost-8181-A4XS.svc URL shortcut (which will start
the browser and display the two entities)
- Continue testing, using your favourite WCF client: a browser, a browser add-on (such as
RESTClient in Firefox), Linqpad, …
o totestthis,youalsoneedtoeditthesourcenameinthecompilebatch(butyoudo
not need to submit the modified batch), e.g.
< set SOURCE=jbon007 > set SOURCE=apow001
COMSCI 335 / 2018 / v1 Page 8 of 8 radu&james
Development
Of course, we will NOT attempt to develop an ODATA service from scratch, even such a simple service restricted to GET queries. Instead, we will “piggy-back” on extant libraries, which allow us to fill in just our specific business requests – using various flavours of LINQ, i.e. in a crisp functional way!
For development, we suggest the following tools: Notepad++, Linqpad or other light weight editors. You are free to use VS, but your submitted project must NOT contain any trace of this and must still have the indicated structure and behaviour!
Note that the model solution has about 100 well-spaced lines, so you probably do not need to write more – much more than this may be a sign of a wrong approach.
Assignment Marks, Deliverables and Submission
This assignment is worth 5 total course marks. Please note the strict COMPSCI policy on plagiarism.
Submit electronically, to the COMPSCI web assignment dropbox, your two source files, named after your UPI, e.g. jbon077.svc.cs and jbon007.svc.fs. The submission size will be limited to 20 KB per student.
Please recheck your projects before submitting, starting from the archive prepared for submission (which is the only thing that the marker will receive from you)!
You can submit several times, but only the last submission will be assessed. Please keep your electronic dropbox receipt!
Deadline
Monday 1 Oct 2018, 18:00! Please do not leave it for the last minute. Remember that you can
resubmit and, by default, we only consider your last submission.
After this deadline, submissions will be still accepted for 4 more days, with gradually increasing penalties, of 0.5% for each hour late. For example:
Monday 1 Oct 2018, 20:00:
Tuesday 2 Oct 2018, 20:00:
Thursday 4 Oct 2018, 18:00:
After this, no more submissions are accepted!
-1%, Tuesday 2 Oct 2017, 18:00: -12% -13%, Wednesday 3 Oct 2017, 18:00: -24% -36%, Friday 5 Oct 2017, 18:00: -48%