Creating and consuming restful web services with wcf
Download
1 / 68

Creating and Consuming RESTful Web Services with WCF - PowerPoint PPT Presentation


  • 73 Views
  • Uploaded on
  • Presentation posted in: General

Creating and Consuming RESTful Web Services with WCF. Ron Jacobs Sr. Technical Evangelist Platform Evangelism Microsoft Corporation. Agenda. What is REST? Is REST SOA? Key REST principles Adventure Works REST API WCF Example Summary. 71 Slides 5 Demos I must be insane!. Resources.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha

Download Presentation

Creating and Consuming RESTful Web Services with WCF

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Creating and consuming restful web services with wcf
Creating and Consuming RESTful Web Services with WCF

Ron Jacobs

Sr. Technical Evangelist

Platform Evangelism

Microsoft Corporation


Agenda
Agenda

  • What is REST?

  • Is REST SOA?

  • Key REST principles

  • Adventure Works REST API WCF Example

  • Summary

71 Slides

5 Demos

I must be insane!


Resources
Resources

  • Leonard Richardson

  • Sam Ruby

  • www.ronjacobs.com

    • Code

    • Slides


What is rest

“Representational state transfer (REST) is a style of software architecture for distributed hypermedia systems such as the World Wide Web.”

http://en.wikipedia.org/wiki/Representational_State_Transfer

What is rest?


What is rest1
What is REST? software architecture for distributed hypermedia systems such as the World Wide Web.”

  • Application state and functionality are resources

  • Every resource has a URI

  • All resources share a uniform interface

HTTP


Is rest soa

“Protocol independence is a bug, not a feature”. software architecture for distributed hypermedia systems such as the World Wide Web.”

- Mark Baker

Is REST SOA?


Is rest soa1
IS REST SOA? software architecture for distributed hypermedia systems such as the World Wide Web.”

  • REST is an architectural style that allows you to implement services with broad reach

  • SOA is about services

    • SOA is not about protocol, transport, format etc.

5 HTTP Messages

18,604 bytes

“You entered: 1”


Key rest principles

“The promise is that if you adhere to REST principles while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit.”

-Stefan Tilkov

http://www.infoq.com/articles/rest-introduction

Key rest principles


Key rest principles1
Key REST Principles while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit.”

  • Give every “thing” an ID

  • Link things together

  • Use standard methods

  • Resources with multiple representations

  • Communicate statelessly


Give every thing an id
Give every “thing” an ID while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit.”

  • Expose thing or collection things with a scheme that is ubiquitous

  • Embrace the URI

    • How to get it (http:// or net.tcp:// or net.msmq:// etc.)

    • Where to get it (example.com)

    • What to get (customer 1234)


Give every thing an id1
Give every “thing” an ID while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit.”

An API like this

Customer C = GetCustomer(1234);

Can be represented like this

http://example.com/customers/1234


Link things together
Link Things Together while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit.”

  • Hypermedia as the engine of application state

    • Just means that you should link things together

    • People or apps can transition state by following links

    • Links can be to the same app or to some other app


Link things together1
Link Things Together while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit.”

<CustomerData>

<Self>http://adventure-works.com/customer/1</Self>

<CompanyName>A Bike Store</CompanyName>

<CustomerID>1</CustomerID>

<EmailAddress>orlando0@adventure-works.com</EmailAddress>

<FirstName>Orlando</FirstName>

<LastName>Gee</LastName>

<Orders>http://adventure-works.com/customer/1/orders</Orders>

<RowID>3f5ae95e-b87d-4aed-95b4-c3797afcb74f</RowID>

</CustomerData>

http://search.live.com/results.aspx?q=Ron+Jacobs&first=11...


Use standard methods
Use Standard Methods while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit.”

public class Resource

{

Resource(Uri u);

Response Get();

Response Post(Request r);

Response Put(Request r);

Response Delete();

Response Head();

}


Shift to resource thinking
Shift to Resource Thinking while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit.”

SQL

INSERT INTO CUSTOMERS (...) VALUES (...)

REST

(POST) http://example.com/customers

<Customer>...</Customer>


Shift to resource thinking1
Shift to Resource Thinking while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit.”

SQL

SELECT FROM CUSTOMERS WHERE ID=567

REST

(GET) http://example.com/customers/567


Resources as operations
Resources as operations while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit.”

  • The result of an operation can be considered a resource

API

var result = CalculateShipping(“Redmond”, “NYC”);

REST

http://example.com/calculateShipping?from=“Redmond”&to=“NYC”


Content negotiation
Content Negotiation while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit.”

  • Allow the client to ask for what they want

  • “I want XML”

  • “I want JSON”

  • “I want …” (HTML, CSV, etc.)

GET /customers/1234 HTTP/1.1

Host: example.com

Accept: text/xml

JSR 311 features the idea

of extensions as a way

to do content negotiation

without the headers as in

/customers.xml

/customers.json

GET /customers/1234 HTTP/1.1

Host: example.com

Accept: text/json


Communicate statelessly
Communicate while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit.”Statelessly

  • Stateless means that every request stands alone

    • Session is not required

    • Can be bookmarked

  • Application State lives on the Client

    • Everything that is needed to complete the request must be included in the request

  • Resource State lives on the server(s)

    • Stored in durable storage (typically)

    • May be cached


Adventure works rest api

Implementation Time while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit.”

adventure works REST API


Adventureworks customer api
AdventureWorks while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit.” Customer API


Http get

“Remember that GET is supposed to be a “safe” operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

-Stefan Tilkov

http://www.infoq.com/articles/tilkov-rest-doubts

HTTP GET


Get customer demo

WebGet operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.” Attribute

UriTemplate

Query String Parameters

GET CUSTOMER DeMO

http://rojacobsxps/AdventureWorksDev/api/customer/1


Webget attribute
WebGet operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.” Attribute

  • WebGet Indicates you want to use an HTTP GET for this method

  • Method name is resource name

  • Arguments are query string parameters

// GET a customer

[OperationContract]

[WebGet]

CustomerDataGetCustomer(string customerId);

http://localhost/service.svc/GetCustomer?customerId=1


Webget uritemplate
WebGet operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”UriTemplate

  • UriTemplate maps the URI to parameters in your method

  • Using parameters in the Uri makes them mandatory, query string parameters are optional.

// GET a customer

[OperationContract]

[WebGet(UriTemplate = "customer/{customerId}")]

CustomerDataGetCustomer(string customerId);

http://localhost/service.svc/Customer/1


Making your first restful service
Making your first operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”RESTful Service

  • Create a WCF Service Library

  • Add a reference / using

    System.ServiceModel.Web

  • Decorate your method with WebGet

  • Modify configuration

    • Change the binding from wsHttpBinding to webHttpBinding

    • Add the webHttp endpoint behavior to the endpoint

      • Note: WCF will start up without this behavior though it is not very useful configuration


Get customers
Get Customers operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

  • Returns a collection of customers from the database

  • Issues

    • Security – you can only see orders you are allowed to see

    • Paging – stateless requests decide where to start

  • REST API

  • SOAP API

http://adventure-works.com/customer

Customer[] GetCustomers()


Paging
Paging operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

  • Allows clients to request a subset of the collection

  • Use Query String parameters to specify start index and count

http://adventure-works.com/customer?start=200&count=25


Gotcha
Gotcha! operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

// GET customers

[OperationContract] [WebGet(UriTemplate="customer?start={start}&count={count}")]

CustomerGroupingDataGetCustomers(int start, int count);

// POST to customers

[OperationContract]

[WebInvoke(UriTemplate = "customer")]

CustomerDataAppendCustomer(CustomerData customer);

http://adventure-works.com/customer

405 Method not allowed


Creating and consuming restful web services with wcf
Why? operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

  • The template matching engine tries to find the best match

  • The more specific a match is, the better

  • When the URL contains just the resource “customer”

  • The match for “customer” is a POST method

    • Return 405 Method not allowed


Creating and consuming restful web services with wcf
Why? operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

  • Solution

    • Don’t include the query string parameters in the UriTemplate

    • Get them instead from the WebOperationContext.Current

    • UriTemplate is now just “customer” for both GET and POST


Solution
Solution operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

// GET customers

[OperationContract] [WebGet(UriTemplate = "customer")]

CustomerGroupingDataGetCustomers(int start, int count);

// POST to customers

[OperationContract]

[WebInvoke(UriTemplate = "customer")]

CustomerDataAppendCustomer(CustomerData customer);

http://localhost/AdventureWorksDev/api/customer

200 Ok


Query string parameters
Query String Parameters operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

private string GetQueryString(string argName)

{

UriTemplateMatch match = WebOperationContext.Current.IncomingRequest.UriTemplateMatch;

try

{

return match.QueryParameters[argName];

}

catch (KeyNotFoundException)

{

return null;

}

}

Query String Parametersare found in here


Caching
Caching operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

  • Use HttpRuntime.Cache to cache items on the server if it makes sense to do so

// Check the cache

CustomerDatacustomerData = (CustomerData)HttpRuntime.Cache[requestUri.ToString()];

// Not found in the cache

if (customerData == null)

{

// Try to get the customer data

customerData = CustomersCollection.GetCustomer(custId);

// Still not found

if (customerData == null)

{

outResponse.SetStatusAsNotFound(string.Format("Customer Id {0} not found", customerId));

}

else // found

{

// Set the headers

outResponse.LastModified = customerData.LastModified;

outResponse.ETag = customerData.ETag.ToString();

CacheCustomer(requestUri, customerData);

}

}


Client caching
Client Caching operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

  • Add Expires or Cache-Control headers to provide clients with hints on caching

  • WCF Default: Cache-Control: private

    • No caching of private results

// Allow client to cache for 5 minutes

outResponse.Headers.Add("Cache-Control", "300");


Conditional get
Conditional GET operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

  • Headers used by clients to save bandwidth if they hold cached data

  • If-Modified-Since: (Date)

    • Return the data only if it has been modified since (Date)


Conditional get1
Conditional GET operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

  • If-None-Matches: (Etag)

    • Return the data only if there are no records matching this tag

  • If the data exists but has not been modified return 304 “Not Modified”

    • The server still has to verify that the resource exists and that it has not changed


Supporting if modified since
Supporting If-Modified-Since operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

  • Your data should have a LastModified value

  • Update it whenever the data is written

// Set the headers

outResponse.LastModified = customerData.LastModified;


Supporting if none matches
Supporting If-None-Matches operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

  • Your data should have a row version

  • This data is returned in an Etag header as an opaque string

// Set the headers

outResponse.ETag = customerData.ETag.ToString();


Conditional get check
Conditional GET Check operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

private static void CheckModifiedSince(

IncomingWebRequestContextinRequest,

OutgoingWebResponseContextoutResponse,

CustomerDatacustomerData)

{

// Get the If-Modified-Since header

DateTime? modifiedSince = GetIfModifiedSince(inRequest);

// Check for conditional get If-Modified-Since

if (modifiedSince != null)

{

if (customerData.LastModified <= modifiedSince)

{

outResponse.SuppressEntityBody = true;

outResponse.StatusCode = HttpStatusCode.NotModified;

}

}

}

Not Modified?

Suppress body

Return 304 “Not Modified”


Get response
GET Response operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET.”

  • 200 OK

    • GET successful

  • 304 Not Modified

    • Conditional GET did not find new data

  • 400 Bad Request

    • Problem with the request of some kind

  • 404 Not Found

    • Resource was not found

  • 500 Internal Server Error

    • Everything else


Http post

“You can use it to create resources underneath a parent resource and you can use it to append extra data onto the current state of a resource.”

- RESTful Web Services

http post


Http post1
HTTP POST resource and you can use it to append extra data onto the current state of a resource.”

  • POST is ambiguously defined in the HTTP spec

  • POST is the second most used RESTful verb

  • Often referred to as POST(a) for “Append”

    • Posting to a collection means to append to that collection

    • Allows the server to determine the ultimate URI


Http post2
HTTP POST resource and you can use it to append extra data onto the current state of a resource.”

  • Problem

    • How to detect duplicate POST requests?

  • Solutions

    • Use PUT (it’s Idempotent by nature)

    • Schemes involving handshaking of some kind between the client and server

    • Client generated identifier for POST


Post to customers
POST to Customers resource and you can use it to append extra data onto the current state of a resource.”

  • Appends a new customer to the collection

  • Issues

    • Security – Are you allowed to create a customer?

    • Idempotency – is this a duplicate POST request?

  • REST API

  • SOAP API

(POST) http://adventure-works.com/customers

CustomerDataAppendCustomer(CustomerData customer);


Post example
POST Example resource and you can use it to append extra data onto the current state of a resource.”

public CustomerDataAppendCustomer(CustomerData customer)

{

OutgoingWebResponseContextoutResponse = WebOperationContext.Current.OutgoingResponse;

try

{

CustomerDatanewCustomer = CustomersCollection.AppendCustomer(customer);

if (newCustomer.CustomerID != 0)

{

outResponse.SetStatusAsCreated(

BuildResourceUri("customer", newCustomer.CustomerID.ToString()));

}

return newCustomer;

}

catch (CustomerRowIDExistsException)

{

outResponse.StatusCode = HttpStatusCode.Conflict;

outResponse.StatusDescription = "RowID exists, it must be unique";

return null;

}

catch (Exception ex)

{

Log.Write(ex);

throw;

}

}


Post a response
POST(a) Response resource and you can use it to append extra data onto the current state of a resource.”

  • 200 OK

    • POST successful

  • 400 Bad Request

    • Problem with the request of some kind

  • 409 Conflict

    • Resource already exists

  • 500 Internal Server Error

    • Everything else


Testing post methods
Testing POST Methods resource and you can use it to append extra data onto the current state of a resource.”

  • Fiddler – http://www.fiddler2.com HTTP proxy

  • Use machine name instead of localhost in URI

    • IIS hosting helps with this

  • Build a request

    • Drag a GET request to the Request Builder

    • Open a GET in Visual Studio for easy formatting of XML

  • Set the Request type to POST

  • Set the request body to valid XML

  • Set the Content-Type: text/xml


Http put

PUT is an idempotent way to create / update a resource resource and you can use it to append extra data onto the current state of a resource.”

http PUT


Http put1
HTTP PUT resource and you can use it to append extra data onto the current state of a resource.”

  • Creates or Updates the resource

    • Completely replaces whatever was there before with the new content

    • Update the cache with new resource

  • Idempotent by design

    • Creating or Updating record 123 multiple times should result in the same value

    • Do NOT do some kind of relative calculation


Put and ids
PUT and IDs resource and you can use it to append extra data onto the current state of a resource.”

  • If you can allow the client to define an ID within a context that is unique, PUT can insert, otherwise PUT is used to update resources

  • REST API

  • SOAP API

  • Note: the first arg comes from the URI, the customer data comes from the request body

(PUT) http://adventure-works.com/customers/123

CustomerDataPutCustomer(string customerId,

CustomerData customer);


Put response
PUT Response resource and you can use it to append extra data onto the current state of a resource.”

  • 200 OK

    • Update successful

  • 201 Created

    • Insert Successful

  • 400 Bad Request

    • Problem with the request of some kind

  • 404 Not Found

    • Resource to update was not found

  • 500 Internal Server Error

    • Everything else


Http delete

DELETE is for uh... well... um... deleting things resource and you can use it to append extra data onto the current state of a resource.”

http DELETE


Delete
DELETE resource and you can use it to append extra data onto the current state of a resource.”

  • Used to delete a resource

  • Issues

    • Security – can you delete a resource

    • Cache – need to remove it from the server cache


Delete response
DELETE Response resource and you can use it to append extra data onto the current state of a resource.”

  • 200 OK

    • Delete successful

  • 400 Bad Request

    • Problem with the request of some kind

  • 404 Not Found

    • Resource to delete was not found

  • 500 Internal Server Error

    • Everything else


Uri mapping
URI Mapping resource and you can use it to append extra data onto the current state of a resource.”


Urimapper http module
UriMapper resource and you can use it to append extra data onto the current state of a resource.” HTTP Module

  • RESTful people do not like ugly URIs

  • ScottGu has Many ways to rewrite URIs

  • HttpModules can rewrite the URIs as they come in

  • Jon Flanders blog

    • Using WCF WebHttpBinding and WebGet with nicer Urls

    • Modified it a bit to support my scenario

http://adventure-works.com/service.svc/customer/1


Gotchca
Gotchca resource and you can use it to append extra data onto the current state of a resource.”!

  • I installed my HttpModule in web.config under <system.web><httpModules>

  • Not working

  • Searched blogs to find out that for IIS 7 you must install under <system.webServer><modules>

  • If your HttpModule does not rewrite the URL correctly you will get 404 errors and have a hard time understanding why


Content negotiation1
Content Negotiation resource and you can use it to append extra data onto the current state of a resource.”

  • Trend is toward an extension syntax

  • Unfortunately you must specify the response format in the WebGet, WebInvoke attribute

  • You can dynamically choose your format by making your service return a stream and then serializing your content directly to the stream

http://adventure-works.com/customers.xhtml

http://adventure-works.com/customers.xml

http://adventure-works.com/customers.json


Two services
Two Services resource and you can use it to append extra data onto the current state of a resource.”

  • apixml.svc for XML

  • apijson.svc for JSON

  • UriMapper code looks for an extension on the resource and maps it to the appropriate service

    • default is XML

  • 2 .SVC files means two classes that implement 2 different contracts


Class diagram
Class Diagram resource and you can use it to append extra data onto the current state of a resource.”


Uri mapping1
URI Mapping resource and you can use it to append extra data onto the current state of a resource.”


Content negotiation demo
Content Negotiation Demo resource and you can use it to append extra data onto the current state of a resource.”

http://rojacobsxps/AdventureWorksDev


Consuming a restful service
Consuming a resource and you can use it to append extra data onto the current state of a resource.”RESTful Service

  • Use WCF or HttpWebRequest

  • Need a ServiceContract interface

    • Copy from service

    • Build from scratch

      • Build UriTemplates that will match up to the service


Data contract schema
Data Contract Schema resource and you can use it to append extra data onto the current state of a resource.”

  • Export Schema from Assembly

    • svcutil foo.dll /dconly

  • Generate data contracts from xsd files

    • svcutil *.xsd /dconly


Using wcf on the client
Using WCF on the Client resource and you can use it to append extra data onto the current state of a resource.”

public CustomerDataGetCustomer(string customerId,

Guid? eTag,

DateTime? modifiedSince)

{

using (var factory = new

WebChannelFactory<IAdventureWorksServiceXml>("AdventureWorks"))

{

IAdventureWorksServiceXml service =

factory.CreateChannel();

using (OperationContextScope scope =

new OperationContextScope( (IContextChannel)service))

{

OutgoingWebRequestContext request =

WebOperationContext.Current.OutgoingRequest;

if (eTag != null)

request.IfNoneMatch = eTag.ToString();

if (modifiedSince != null)

{

DateTimeFormatInfoformatInfo =

CultureInfo.InvariantCulture.DateTimeFormat;

// RFC1123Pattern

request.IfModifiedSince =

modifiedSince.Value.ToString("r", formatInfo);

}

return service.GetCustomer(customerId);

}

}

}

You must create

a scope to access the context


Summary
Summary resource and you can use it to append extra data onto the current state of a resource.”

  • RESTful services extend the reach of HTTP to your SOA

  • RESTful design is harder than you might think

  • Implementation has some tricky issues to overcome


ad
  • Login