restful api design best practices using asp.net web api
TRANSCRIPT
![Page 1: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/1.jpg)
#NeverRestRESTful API Design Best
PracticesUsing ASP.NET Web API
Spencer Schneidenbach
@schneidenbach
![Page 3: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/3.jpg)
Why?@schneidenbach#NeverRest
![Page 4: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/4.jpg)
Developers have the power of choice
@schneidenbach#NeverRest
![Page 5: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/5.jpg)
Long-term benefits
@schneidenbach#NeverRest
Go from 0 to “make magic happen”
Learn stuff and manage exceptions
![Page 6: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/6.jpg)
Developers have the power of choice
@schneidenbach#NeverRest
![Page 7: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/7.jpg)
Developers have an opportunity create something better than the
competition
@schneidenbach#NeverRest
![Page 8: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/8.jpg)
API Design is UX for Developers
@schneidenbach#NeverRest
![Page 9: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/9.jpg)
This quote sums it up nicely
If you don’t make usability a priority, you’ll never have to worry about scalability.
-Kirsten Hunter @synedra
@schneidenbach#NeverRest
![Page 10: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/10.jpg)
Some common themes
@schneidenbach#NeverRest
![Page 11: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/11.jpg)
@schneidenbach#NeverRest
![Page 12: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/12.jpg)
Simple != Easy
@schneidenbach#NeverRest
![Page 13: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/13.jpg)
There’s No Silver Bullet
@schneidenbach#NeverRest
![Page 14: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/14.jpg)
What is REST?
Representational State Transfer
@schneidenbach#NeverRest
![Page 15: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/15.jpg)
Uniform InterfaceCode on Demand
(optional)Layered
StatelessCacheableClient-Server
The Six Constraints of REST
@schneidenbach#NeverRest
![Page 16: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/16.jpg)
Resource identification
Uniform Interface constraint
Content-Type:
application/json
Resource manipulation with
representations
Self-descriptive Hypermedia as the engine of
application state (HATEOAS)
GET /employees/1234
PUT /employees/1234
@schneidenbach#NeverRest
![Page 17: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/17.jpg)
What is a RESTful API?RESTful API == an API that follows REST architecture
Term has been sort of co-opted
REST != JSONREST != HTTP
Lots of people say “REST API” when they really mean HTTP JSON API
@schneidenbach#NeverRest
![Page 18: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/18.jpg)
Pragmatic REST
RESTful API != Good API
@schneidenbach#NeverRest
![Page 19: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/19.jpg)
Do what makes sense. Throw out the rest.
Is that vague enough for you?
@schneidenbach#NeverRest
![Page 20: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/20.jpg)
MaintainDocument
ImplementDesign
API Design Process
@schneidenbach#NeverRest
![Page 21: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/21.jpg)
Designing your RESTful APII HAVE ONE RULE… okay I actually have two rules
@schneidenbach#NeverRest
![Page 22: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/22.jpg)
KISS(or, Keep it Simple, Stupid)
@schneidenbach#NeverRest
![Page 23: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/23.jpg)
KISS
Don’t be creative.
Provide what is necessary – no more, no less.
Use a handful of HTTP status codes.
@schneidenbach#NeverRest
![Page 24: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/24.jpg)
403 Forbidden(aka you can’t do that)
401 Unauthorized(aka not authenticated)
404 Not Found
400 Bad Request201 Created200 OK
Good HTTP Codes
@schneidenbach#NeverRest
![Page 25: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/25.jpg)
KISS
{ "id": 1234, "active": true, "nameId": 345}
{ "id": 345, "name": "Acme"}
Customer API Name API
GET /customers/1234 GET /names/345
@schneidenbach#NeverRest
![Page 26: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/26.jpg)
KISS
That’s TWO REQUESTS per GET
That’s TWO REQUESTS per POST
What’s the point?
@schneidenbach#NeverRest
![Page 27: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/27.jpg)
Don’t let your specific implementations leak if they are
hard to use or understand.
@schneidenbach#NeverRest
![Page 28: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/28.jpg)
KISS
{ "id": 1234, "active": true, "name": "Acme"}
Customer API
GET /customers/1234
@schneidenbach#NeverRest
![Page 29: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/29.jpg)
KISS
TheoryAnnexThresholdLilia
@schneidenbach#NeverRest
![Page 30: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/30.jpg)
KISSInactiveDeletedVisibleRetired
@schneidenbach#NeverRest
![Page 31: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/31.jpg)
Second big rule – Be Consistent
Be consistent with accepted best practices.
Be consistent with yourself.
@schneidenbach#NeverRest
![Page 32: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/32.jpg)
PATCHDELETE
POSTPUTGET
Understanding verbs
Remember consistency!@schneidenbach#NeverRest
![Page 33: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/33.jpg)
Don’t mutate data with GETs.
@schneidenbach#NeverRest
![Page 34: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/34.jpg)
Resource identificationNouns vs. verbs
Basically, use plural nouns
@schneidenbach#NeverRest
![Page 35: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/35.jpg)
{ "invoices": [ { ... }, { ... } ]}
GET /customers/1234/invoic
es
GET /customers/1234?expand=invoices
Within the parent object
Sub-resource strategies
As a separate request Using an expand parameter
Be consistent, but be flexible when it makes sense
@schneidenbach#NeverRest
![Page 36: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/36.jpg)
GET considerations
SortingFiltering
Paging@schneidenbach#NeverRest
![Page 37: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/37.jpg)
Sorting/Ordering
$orderBy=name desc
$orderBy=name desc,hireDate
@schneidenbach#NeverRest
![Page 38: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/38.jpg)
Filtering
$filter=(name eq 'Milk' or name eq 'Eggs') and price lt 2.55
@schneidenbach#NeverRest
![Page 39: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/39.jpg)
Sorting and filtering for free
Google “OData web api”
@schneidenbach#NeverRest
![Page 40: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/40.jpg)
PagingGET /customers? page=1 & pageSize=1000
{"pageNumber": 1,"results": [...],"nextPage": "/customers?page=2"
}
Good paging example on my blog: rest.schneids.net
@schneidenbach#NeverRest
![Page 41: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/41.jpg)
Do I need to sort/page/filter?
Maybe!
What do your consumers need?
@schneidenbach#NeverRest
![Page 42: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/42.jpg)
Versioning
Your APIs should stand a test of time
@schneidenbach#NeverRest
![Page 43: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/43.jpg)
Versioning
GET /customersHost: contoso.comAccept: application/jsonX-Api-Version: 1
@schneidenbach#NeverRest
POST /customersHost: contoso.comAccept: application/jsonX-Api-Version: 2.0
![Page 44: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/44.jpg)
Versioning
Use URL versioning@schneidenbach#NeverRest
GET /v1/customersHost: contoso.comAccept: application/json
![Page 45: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/45.jpg)
Error reporting
Errors are going to happen.
How will you manage them?
@schneidenbach#NeverRest
![Page 46: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/46.jpg)
Error reporting
{ "name": "Arana Software"}
@schneidenbach#NeverRest
Requires name and state
POST /vendors
400 Bad Request
Content-Type: application/json
"State is required."
{ "firstName": "Spencer"}
Requires first and last name
POST /employees
400 Bad Request
Content-Type: application/json
{
"errorMessage": "Your request was invalid."
}
![Page 47: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/47.jpg)
Error reporting
@schneidenbach#NeverRest
![Page 48: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/48.jpg)
Error reporting
Make finding and fixing errors as easy on your consumer as possible.
@schneidenbach#NeverRest
![Page 49: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/49.jpg)
AuthenticationEncryption
Security
@schneidenbach#NeverRest
![Page 50: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/50.jpg)
Use SSL.
Don’t roll your own encryption.
Pick an auth strategy that isn’t Basic.
@schneidenbach#NeverRest
Security
![Page 51: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/51.jpg)
Ok, time for some code examplesand practical advise
@schneidenbach#NeverRest
![Page 52: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/52.jpg)
@schneidenbach#NeverRest
Controller Anatomy
![Page 53: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/53.jpg)
@schneidenbach#NeverRest
![Page 54: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/54.jpg)
@schneidenbach#NeverRest
![Page 55: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/55.jpg)
@schneidenbach#NeverRest
![Page 56: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/56.jpg)
Use DTOs/per-request objects@schneidenbach#NeverRest
![Page 57: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/57.jpg)
Separation of concerns
@schneidenbach#NeverRest
![Page 58: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/58.jpg)
@schneidenbach#NeverRest
![Page 59: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/59.jpg)
@schneidenbach#NeverRest
![Page 60: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/60.jpg)
Separation of concerns
@schneidenbach#NeverRest
Controllers should know “where,” not ”how.”
![Page 61: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/61.jpg)
@schneidenbach#NeverRest
![Page 62: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/62.jpg)
Validation
@schneidenbach#NeverRest
![Page 63: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/63.jpg)
Validation
Validate. Validate. Validate.
@schneidenbach#NeverRest
Separate validation logic from object.
Google Fluent Validation
![Page 64: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/64.jpg)
Controller
Good Architecture
Request Handler/ServiceValidator
Enforce separation of concerns for maintainability and testability.
Google MediatR
![Page 65: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/65.jpg)
Gotchas/ErrorsFormatting
SchemaParametersEndpoints
Documentation
@schneidenbach#NeverRest
![Page 66: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/66.jpg)
Documentation
A good API lives and dies by its documentation.
(you should tweet that out)
@schneidenbach#NeverRest
![Page 67: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/67.jpg)
Maintaining your APIVendor: “Hey, we’ve made some under-the-cover changes to our endpoint. It shouldn’t impact you, but let us know if it breaks something.”
Us: ”Okay. Can you release it to test first so we can run our integration tests against the endpoint and make sure everything works?”
Vendor: ”Well, actually we need it ASAP, so we’re releasing to prod in an hour.”
@schneidenbach#NeverRest
![Page 68: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/68.jpg)
Maintaining your API
Fix bugs and optimize.
Don’t introduce breaking changes like removing properties.
@schneidenbach#NeverRest
![Page 69: RESTful API Design Best Practices Using ASP.NET Web API](https://reader034.vdocuments.site/reader034/viewer/2022042517/589e52dc1a28ab1c7f8b67e3/html5/thumbnails/69.jpg)
Thank you!Slides, resources at rest.schneids.net
schneids.net
@schneidenbach