SlideShare une entreprise Scribd logo
1  sur  27
Télécharger pour lire hors ligne
BEAUTIFUL REST APIs
in ASP.NET Core
Nate Barbettini
@nbarbettini
recaffeinate.co
.ws
Overview
● Why is API design important?
● HATEOAS (Hypertext As The Engine Of Application State)
● REST APIs in ASP.NET Core
/getAccount?id=17
Bad REST API design
/getAccount?all=1&includePosts=1
/getAllAccounts
/updateAccount?id=17
/createAccount
/findPostsByAccountId?account=17
/accountSearch?lname=Skywalker
/getAccount?id=17&includePosts=1
/getAccount?id=17&format=json
/getAllAccountsJson
/updateAccount?id=17&return=json
/createAccountJson
/accountSearch?lname=Skywalker&xml=1
/findPostsByAccountIdJSON?account=17
/getAllPosts?filter=account&id=17
/countAccounts
/partialUpdateAccount?id=17
/getPostCount?id=17
/deleteUser
HATEOAS, yo!
"A REST API should be entered with no prior knowledge beyond the initial URI (bookmark)
and set of standardized media types that are appropriate for the intended audience (i.e.,
expected to be understood by any client that might use the API). From that point on, all
application state transitions must be driven by client selection of server-provided choices
that are present in the received representations or implied by the user’s manipulation of
those representations." ~ Dr. Fielding
Tl;dr The API responses themselves
should document what you are allowed to
do and where you can go.
If you can get to the root (/), you should be
able to “travel” anywhere else in the API.
Good REST API design should...
● Be discoverable and self-documenting
● Represent resources and collections
● Represent actions using HTTP verbs
● KISS!
Revisiting the API example
/users GET: List all users
POST or PUT: Create a user
/users/17 GET: Retrieve a single user
POST or PUT: Update user details
DELETE: Delete this user
/users/17/posts GET: Get the user’s posts
POST: Create a post
/users?lname=Skywalker
Search
/users/17?include=posts
Include linked data
A specification for REST+JSON APIs
The ION spec: https://github.com/ionwg/ion-doc
Getting a single user
GET /users/17
{
"meta": { "href": "https://example.io/users/17" },
"firstName": "Luke",
"lastName": "Skywalker"
}
Getting a list of users
GET /users
{
"meta": { "href": "https://example.io/users", "rel": ["collection"] },
"items": [{
"meta": { "href": "https://example.io/users/17" },
"firstName": "Luke",
"lastName": "Skywalker"
}, {
"meta": { "href": "https://example.io/users/18" },
"firstName": "Han",
"lastName": "Solo"
}]
}
Discoverable forms
GET /users
{
...
"create": {
"meta": {
"href": "https://example.io/users",
"rel": ["create-form"],
"method": "post"
},
"items": [
{ "name": "firstName" },
{ "name": "lastName" }
]
}
}
Discoverable search
GET /users
{
...
"search": {
"meta": {
"href": "https://example.io/users",
"rel": ["search-form"],
"method": "get"
},
"items": [
{ "name": "fname" },
{ "name": "lname" }
]
}
}
The starting point (API root)
GET /
{
"meta": { "href": "https://example.io/" },
"users": {
"meta": {
"href": "https://example.io/users",
"rel": ["collection"],
}
}
}
● Install the .NET Core SDK - http://dot.net/core
● If you’re using Visual Studio:
○ Install the latest updates (Update 3)
○ Install the .NET Core tooling - https://go.microsoft.com/fwlink/?LinkID=824849
● Or, install Visual Studio Code
● Create a new project from the ASP.NET Core (.NET Core) template
● Pick the API subtemplate
● Ready to run!
Getting started with ASP.NET Core
Getting a single user
GET /users/17
{
"meta": { "href": "https://example.io/users/17" },
"firstName": "Luke",
"lastName": "Skywalker"
}
public class Link
{
public string Href { get; set; }
}
public abstract class Resource
{
[JsonProperty(Order = -2)]
public Link Meta { get; set; }
}
Getting a single user
public class User : Resource
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Getting a single user
[Route("/users")]
public class UsersController : Controller
{
private readonly BulletinBoardDbContext _context;
private readonly IUrlHelperFactory _urlHelperFactory;
public UsersController(
BulletinBoardDbContext context,
IUrlHelperFactory urlHelperFactory)
{
_context = context;
_urlHelperFactory = urlHelperFactory;
}
Getting a single user
[Route("{id}")]
public async Task<IActionResult> GetUser(string id)
{
var user = await _context.Users.SingleOrDefaultAsync(x => x.Id == id);
if (user == null) return NotFound();
var urlHelper = _urlHelperFactory.GetUrlHelper(ControllerContext);
var url = urlHelper.Link("default", new
{
controller = "users",
id = user.Id
});
var response = new User()
{
Meta = new Link() { Href = url },
FirstName = user.FirstName,
LastName = user.LastName
};
return Ok(response);
}
Getting a single user
Getting a list of users
GET /users
{
"meta": { "href": "https://example.io/users", "rel": ["collection"] },
"items": [{
"meta": { "href": "https://example.io/users/17" },
"firstName": "Luke",
"lastName": "Skywalker"
}, {
"meta": { "href": "https://example.io/users/18" },
"firstName": "Han",
"lastName": "Solo"
}]
}
Getting a list of users
public class Link
{
public string Href { get; set; }
[JsonProperty(PropertyName = "rel", NullValueHandling = NullValueHandling.Ignore)]
public string[] Relations { get; set; }
}
Getting a list of users
public class Collection<T> : Resource
{
public T[] Items { get; set; }
}
Getting a list of users
public async Task<IActionResult> GetAll()
{
var urlHelper = _urlHelperFactory.GetUrlHelper(ControllerContext);
var allUsers = await _context.Users.ToArrayAsync();
var projected = allUsers.Select(x => new User() {
Meta = new Link() {
Href = urlHelper.Link("default", new { controller = "users", id = x.Id })
},
FirstName = x.FirstName,
LastName = x.LastName
});
var response = new Collection<User>()
{
Meta = new Link() {
Href = urlHelper.Link("default", new { controller = "users" }),
Relations = new string[] {"collection"},
},
Items = projected.ToArray()
};
return Ok(response);
}
The starting point (API root)
GET /
{
"meta": { "href": "https://example.io/" },
"users": {
"meta": {
"href": "https://example.io/users",
"rel": ["collection"],
}
}
}
Adding a root route
[Route("/")]
public class RootController : Controller
{
private readonly IUrlHelperFactory _urlHelperFactory;
public RootController(IUrlHelperFactory urlHelperFactory)
{
_urlHelperFactory = urlHelperFactory;
}
public IActionResult Get()
{
var urlHelper = _urlHelperFactory.GetUrlHelper(ControllerContext);
var response = new {
meta = new Link() {
Href = urlHelper.Link("default", new { controller = "root" })
},
users = new Link() {
Href = urlHelper.Link("default", new { controller = "users" }),
Relations = new string[] {"collection"}
}
};
return Ok(response);
}
}
Building and running (anywhere!)
> dotnet build
(...)
Done.
> dotnet run
(...)
Listening on https://localhost:5000
Next Steps
● Full example
https://github.com/nbarbettini/beautiful-rest-api-aspnetcore
● ION draft spec
https://github.com/ionwg/ion-doc
Thank you!
Nate Barbettini
@nbarbettini
recaffeinate.co
.ws

Contenu connexe

Tendances

Best Practices for Architecting a Pragmatic Web API.
Best Practices for Architecting a Pragmatic Web API.Best Practices for Architecting a Pragmatic Web API.
Best Practices for Architecting a Pragmatic Web API.Mario Cardinal
 
Designing a beautiful REST json api
Designing a beautiful REST json apiDesigning a beautiful REST json api
Designing a beautiful REST json api0x07de
 
External Data Access with jQuery
External Data Access with jQueryExternal Data Access with jQuery
External Data Access with jQueryDoncho Minkov
 
Understanding REST
Understanding RESTUnderstanding REST
Understanding RESTNitin Pande
 
Best practices for RESTful web service design
Best practices for RESTful web service designBest practices for RESTful web service design
Best practices for RESTful web service designRamin Orujov
 
RESTful API Design Best Practices Using ASP.NET Web API
RESTful API Design Best Practices Using ASP.NET Web APIRESTful API Design Best Practices Using ASP.NET Web API
RESTful API Design Best Practices Using ASP.NET Web API💻 Spencer Schneidenbach
 
The never-ending REST API design debate -- Devoxx France 2016
The never-ending REST API design debate -- Devoxx France 2016The never-ending REST API design debate -- Devoxx France 2016
The never-ending REST API design debate -- Devoxx France 2016Restlet
 
GraphQL & Relay - 串起前後端世界的橋樑
GraphQL & Relay - 串起前後端世界的橋樑GraphQL & Relay - 串起前後端世界的橋樑
GraphQL & Relay - 串起前後端世界的橋樑Pokai Chang
 
Austin Day of Rest - Introduction
Austin Day of Rest - IntroductionAustin Day of Rest - Introduction
Austin Day of Rest - IntroductionHandsOnWP.com
 
RESTful Web API and MongoDB go for a pic nic
RESTful Web API and MongoDB go for a pic nicRESTful Web API and MongoDB go for a pic nic
RESTful Web API and MongoDB go for a pic nicNicola Iarocci
 
Log File Analysis: The most powerful tool in your SEO toolkit
Log File Analysis: The most powerful tool in your SEO toolkitLog File Analysis: The most powerful tool in your SEO toolkit
Log File Analysis: The most powerful tool in your SEO toolkitTom Bennet
 
Rest presentation
Rest  presentationRest  presentation
Rest presentationsrividhyau
 
Representational State Transfer (REST) and HATEOAS
Representational State Transfer (REST) and HATEOASRepresentational State Transfer (REST) and HATEOAS
Representational State Transfer (REST) and HATEOASGuy K. Kloss
 
Creating 3rd Generation Web APIs with Hydra
Creating 3rd Generation Web APIs with HydraCreating 3rd Generation Web APIs with Hydra
Creating 3rd Generation Web APIs with HydraMarkus Lanthaler
 
Building Next-Generation Web APIs with JSON-LD and Hydra
Building Next-Generation Web APIs with JSON-LD and HydraBuilding Next-Generation Web APIs with JSON-LD and Hydra
Building Next-Generation Web APIs with JSON-LD and HydraMarkus Lanthaler
 
Understanding REST APIs in 5 Simple Steps
Understanding REST APIs in 5 Simple StepsUnderstanding REST APIs in 5 Simple Steps
Understanding REST APIs in 5 Simple StepsTessa Mero
 
Data Exploration with Elasticsearch
Data Exploration with ElasticsearchData Exploration with Elasticsearch
Data Exploration with ElasticsearchAleksander Stensby
 

Tendances (19)

Best Practices for Architecting a Pragmatic Web API.
Best Practices for Architecting a Pragmatic Web API.Best Practices for Architecting a Pragmatic Web API.
Best Practices for Architecting a Pragmatic Web API.
 
Designing a beautiful REST json api
Designing a beautiful REST json apiDesigning a beautiful REST json api
Designing a beautiful REST json api
 
External Data Access with jQuery
External Data Access with jQueryExternal Data Access with jQuery
External Data Access with jQuery
 
Understanding REST
Understanding RESTUnderstanding REST
Understanding REST
 
Best practices for RESTful web service design
Best practices for RESTful web service designBest practices for RESTful web service design
Best practices for RESTful web service design
 
RESTful API Design Best Practices Using ASP.NET Web API
RESTful API Design Best Practices Using ASP.NET Web APIRESTful API Design Best Practices Using ASP.NET Web API
RESTful API Design Best Practices Using ASP.NET Web API
 
The never-ending REST API design debate -- Devoxx France 2016
The never-ending REST API design debate -- Devoxx France 2016The never-ending REST API design debate -- Devoxx France 2016
The never-ending REST API design debate -- Devoxx France 2016
 
GraphQL & Relay - 串起前後端世界的橋樑
GraphQL & Relay - 串起前後端世界的橋樑GraphQL & Relay - 串起前後端世界的橋樑
GraphQL & Relay - 串起前後端世界的橋樑
 
RESTful Web Services
RESTful Web ServicesRESTful Web Services
RESTful Web Services
 
Rest API
Rest APIRest API
Rest API
 
Austin Day of Rest - Introduction
Austin Day of Rest - IntroductionAustin Day of Rest - Introduction
Austin Day of Rest - Introduction
 
RESTful Web API and MongoDB go for a pic nic
RESTful Web API and MongoDB go for a pic nicRESTful Web API and MongoDB go for a pic nic
RESTful Web API and MongoDB go for a pic nic
 
Log File Analysis: The most powerful tool in your SEO toolkit
Log File Analysis: The most powerful tool in your SEO toolkitLog File Analysis: The most powerful tool in your SEO toolkit
Log File Analysis: The most powerful tool in your SEO toolkit
 
Rest presentation
Rest  presentationRest  presentation
Rest presentation
 
Representational State Transfer (REST) and HATEOAS
Representational State Transfer (REST) and HATEOASRepresentational State Transfer (REST) and HATEOAS
Representational State Transfer (REST) and HATEOAS
 
Creating 3rd Generation Web APIs with Hydra
Creating 3rd Generation Web APIs with HydraCreating 3rd Generation Web APIs with Hydra
Creating 3rd Generation Web APIs with Hydra
 
Building Next-Generation Web APIs with JSON-LD and Hydra
Building Next-Generation Web APIs with JSON-LD and HydraBuilding Next-Generation Web APIs with JSON-LD and Hydra
Building Next-Generation Web APIs with JSON-LD and Hydra
 
Understanding REST APIs in 5 Simple Steps
Understanding REST APIs in 5 Simple StepsUnderstanding REST APIs in 5 Simple Steps
Understanding REST APIs in 5 Simple Steps
 
Data Exploration with Elasticsearch
Data Exploration with ElasticsearchData Exploration with Elasticsearch
Data Exploration with Elasticsearch
 

En vedette

Stormpath 101: Spring Boot + Spring Security
Stormpath 101: Spring Boot + Spring SecurityStormpath 101: Spring Boot + Spring Security
Stormpath 101: Spring Boot + Spring SecurityStormpath
 
Secure API Services in Node with Basic Auth and OAuth2
Secure API Services in Node with Basic Auth and OAuth2Secure API Services in Node with Basic Auth and OAuth2
Secure API Services in Node with Basic Auth and OAuth2Stormpath
 
Storing User Files with Express, Stormpath, and Amazon S3
Storing User Files with Express, Stormpath, and Amazon S3Storing User Files with Express, Stormpath, and Amazon S3
Storing User Files with Express, Stormpath, and Amazon S3Stormpath
 
JWTs for CSRF and Microservices
JWTs for CSRF and MicroservicesJWTs for CSRF and Microservices
JWTs for CSRF and MicroservicesStormpath
 
Mobile Authentication for iOS Applications - Stormpath 101
Mobile Authentication for iOS Applications - Stormpath 101Mobile Authentication for iOS Applications - Stormpath 101
Mobile Authentication for iOS Applications - Stormpath 101Stormpath
 
Token Authentication in ASP.NET Core
Token Authentication in ASP.NET CoreToken Authentication in ASP.NET Core
Token Authentication in ASP.NET CoreStormpath
 
Custom Data Search with Stormpath
Custom Data Search with StormpathCustom Data Search with Stormpath
Custom Data Search with StormpathStormpath
 
Spring Boot Authentication...and More!
Spring Boot Authentication...and More! Spring Boot Authentication...and More!
Spring Boot Authentication...and More! Stormpath
 
JWTs in Java for CSRF and Microservices
JWTs in Java for CSRF and MicroservicesJWTs in Java for CSRF and Microservices
JWTs in Java for CSRF and MicroservicesStormpath
 
Instant Security & Scalable User Management with Spring Boot
Instant Security & Scalable User Management with Spring BootInstant Security & Scalable User Management with Spring Boot
Instant Security & Scalable User Management with Spring BootStormpath
 
Multi-Tenancy with Spring Boot
Multi-Tenancy with Spring Boot Multi-Tenancy with Spring Boot
Multi-Tenancy with Spring Boot Stormpath
 
The Ultimate Guide to Mobile API Security
The Ultimate Guide to Mobile API SecurityThe Ultimate Guide to Mobile API Security
The Ultimate Guide to Mobile API SecurityStormpath
 
Browser Security 101
Browser Security 101 Browser Security 101
Browser Security 101 Stormpath
 
REST API Security: OAuth 2.0, JWTs, and More!
REST API Security: OAuth 2.0, JWTs, and More!REST API Security: OAuth 2.0, JWTs, and More!
REST API Security: OAuth 2.0, JWTs, and More!Stormpath
 
Building Secure User Interfaces With JWTs (JSON Web Tokens)
Building Secure User Interfaces With JWTs (JSON Web Tokens)Building Secure User Interfaces With JWTs (JSON Web Tokens)
Building Secure User Interfaces With JWTs (JSON Web Tokens)Stormpath
 
Getting Started With Angular
Getting Started With AngularGetting Started With Angular
Getting Started With AngularStormpath
 
Securing Web Applications with Token Authentication
Securing Web Applications with Token AuthenticationSecuring Web Applications with Token Authentication
Securing Web Applications with Token AuthenticationStormpath
 
Build a REST API for your Mobile Apps using Node.js
Build a REST API for your Mobile Apps using Node.jsBuild a REST API for your Mobile Apps using Node.js
Build a REST API for your Mobile Apps using Node.jsStormpath
 
Token Authentication for Java Applications
Token Authentication for Java ApplicationsToken Authentication for Java Applications
Token Authentication for Java ApplicationsStormpath
 
So long scrum, hello kanban
So long scrum, hello kanbanSo long scrum, hello kanban
So long scrum, hello kanbanStormpath
 

En vedette (20)

Stormpath 101: Spring Boot + Spring Security
Stormpath 101: Spring Boot + Spring SecurityStormpath 101: Spring Boot + Spring Security
Stormpath 101: Spring Boot + Spring Security
 
Secure API Services in Node with Basic Auth and OAuth2
Secure API Services in Node with Basic Auth and OAuth2Secure API Services in Node with Basic Auth and OAuth2
Secure API Services in Node with Basic Auth and OAuth2
 
Storing User Files with Express, Stormpath, and Amazon S3
Storing User Files with Express, Stormpath, and Amazon S3Storing User Files with Express, Stormpath, and Amazon S3
Storing User Files with Express, Stormpath, and Amazon S3
 
JWTs for CSRF and Microservices
JWTs for CSRF and MicroservicesJWTs for CSRF and Microservices
JWTs for CSRF and Microservices
 
Mobile Authentication for iOS Applications - Stormpath 101
Mobile Authentication for iOS Applications - Stormpath 101Mobile Authentication for iOS Applications - Stormpath 101
Mobile Authentication for iOS Applications - Stormpath 101
 
Token Authentication in ASP.NET Core
Token Authentication in ASP.NET CoreToken Authentication in ASP.NET Core
Token Authentication in ASP.NET Core
 
Custom Data Search with Stormpath
Custom Data Search with StormpathCustom Data Search with Stormpath
Custom Data Search with Stormpath
 
Spring Boot Authentication...and More!
Spring Boot Authentication...and More! Spring Boot Authentication...and More!
Spring Boot Authentication...and More!
 
JWTs in Java for CSRF and Microservices
JWTs in Java for CSRF and MicroservicesJWTs in Java for CSRF and Microservices
JWTs in Java for CSRF and Microservices
 
Instant Security & Scalable User Management with Spring Boot
Instant Security & Scalable User Management with Spring BootInstant Security & Scalable User Management with Spring Boot
Instant Security & Scalable User Management with Spring Boot
 
Multi-Tenancy with Spring Boot
Multi-Tenancy with Spring Boot Multi-Tenancy with Spring Boot
Multi-Tenancy with Spring Boot
 
The Ultimate Guide to Mobile API Security
The Ultimate Guide to Mobile API SecurityThe Ultimate Guide to Mobile API Security
The Ultimate Guide to Mobile API Security
 
Browser Security 101
Browser Security 101 Browser Security 101
Browser Security 101
 
REST API Security: OAuth 2.0, JWTs, and More!
REST API Security: OAuth 2.0, JWTs, and More!REST API Security: OAuth 2.0, JWTs, and More!
REST API Security: OAuth 2.0, JWTs, and More!
 
Building Secure User Interfaces With JWTs (JSON Web Tokens)
Building Secure User Interfaces With JWTs (JSON Web Tokens)Building Secure User Interfaces With JWTs (JSON Web Tokens)
Building Secure User Interfaces With JWTs (JSON Web Tokens)
 
Getting Started With Angular
Getting Started With AngularGetting Started With Angular
Getting Started With Angular
 
Securing Web Applications with Token Authentication
Securing Web Applications with Token AuthenticationSecuring Web Applications with Token Authentication
Securing Web Applications with Token Authentication
 
Build a REST API for your Mobile Apps using Node.js
Build a REST API for your Mobile Apps using Node.jsBuild a REST API for your Mobile Apps using Node.js
Build a REST API for your Mobile Apps using Node.js
 
Token Authentication for Java Applications
Token Authentication for Java ApplicationsToken Authentication for Java Applications
Token Authentication for Java Applications
 
So long scrum, hello kanban
So long scrum, hello kanbanSo long scrum, hello kanban
So long scrum, hello kanban
 

Similaire à Building Beautiful REST APIs in ASP.NET Core

The JSON REST API for WordPress
The JSON REST API for WordPressThe JSON REST API for WordPress
The JSON REST API for WordPressTaylor Lovett
 
Making Java REST with JAX-RS 2.0
Making Java REST with JAX-RS 2.0Making Java REST with JAX-RS 2.0
Making Java REST with JAX-RS 2.0Dmytro Chyzhykov
 
AMS, API, RAILS and a developer, a Love Story
AMS, API, RAILS and a developer, a Love StoryAMS, API, RAILS and a developer, a Love Story
AMS, API, RAILS and a developer, a Love StoryJoão Moura
 
Diseño y Desarrollo de APIs
Diseño y Desarrollo de APIsDiseño y Desarrollo de APIs
Diseño y Desarrollo de APIsRaúl Neis
 
GraphQL Los Angeles Meetup Slides
GraphQL Los Angeles Meetup SlidesGraphQL Los Angeles Meetup Slides
GraphQL Los Angeles Meetup SlidesGrant Miller
 
Tk2323 lecture 9 api json
Tk2323 lecture 9   api jsonTk2323 lecture 9   api json
Tk2323 lecture 9 api jsonMengChun Lam
 
RESTful API 제대로 만들기
RESTful API 제대로 만들기RESTful API 제대로 만들기
RESTful API 제대로 만들기Juwon Kim
 
jSession #4 - Maciej Puchalski - Zaawansowany retrofit
jSession #4 - Maciej Puchalski - Zaawansowany retrofitjSession #4 - Maciej Puchalski - Zaawansowany retrofit
jSession #4 - Maciej Puchalski - Zaawansowany retrofitjSession
 
Golang slidesaudrey
Golang slidesaudreyGolang slidesaudrey
Golang slidesaudreyAudrey Lim
 
Semantic Web & TYPO3
Semantic Web & TYPO3Semantic Web & TYPO3
Semantic Web & TYPO3André Wuttig
 
Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss Andres Almiray
 
David Gómez G. - Hypermedia APIs for headless platforms and Data Integration ...
David Gómez G. - Hypermedia APIs for headless platforms and Data Integration ...David Gómez G. - Hypermedia APIs for headless platforms and Data Integration ...
David Gómez G. - Hypermedia APIs for headless platforms and Data Integration ...Codemotion
 
Cdm mil-18 - hypermedia ap is for headless platforms and data integration
Cdm mil-18 - hypermedia ap is for headless platforms and data integrationCdm mil-18 - hypermedia ap is for headless platforms and data integration
Cdm mil-18 - hypermedia ap is for headless platforms and data integrationDavid Gómez García
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4DEVCON
 
Hypermedia APIs and HATEOAS / Wix Engineering
Hypermedia APIs and HATEOAS / Wix EngineeringHypermedia APIs and HATEOAS / Wix Engineering
Hypermedia APIs and HATEOAS / Wix EngineeringVladimir Tsukur
 
RESTful JSON web databases
RESTful JSON web databasesRESTful JSON web databases
RESTful JSON web databaseskriszyp
 
Specification-Driven Development of REST APIs by Alexander Zinchuk
Specification-Driven Development of REST APIs by Alexander Zinchuk   Specification-Driven Development of REST APIs by Alexander Zinchuk
Specification-Driven Development of REST APIs by Alexander Zinchuk OdessaJS Conf
 
Example-driven Web API Specification Discovery
Example-driven Web API Specification DiscoveryExample-driven Web API Specification Discovery
Example-driven Web API Specification DiscoveryJavier Canovas
 

Similaire à Building Beautiful REST APIs in ASP.NET Core (20)

The JSON REST API for WordPress
The JSON REST API for WordPressThe JSON REST API for WordPress
The JSON REST API for WordPress
 
Making Java REST with JAX-RS 2.0
Making Java REST with JAX-RS 2.0Making Java REST with JAX-RS 2.0
Making Java REST with JAX-RS 2.0
 
AMS, API, RAILS and a developer, a Love Story
AMS, API, RAILS and a developer, a Love StoryAMS, API, RAILS and a developer, a Love Story
AMS, API, RAILS and a developer, a Love Story
 
Diseño y Desarrollo de APIs
Diseño y Desarrollo de APIsDiseño y Desarrollo de APIs
Diseño y Desarrollo de APIs
 
GraphQL Los Angeles Meetup Slides
GraphQL Los Angeles Meetup SlidesGraphQL Los Angeles Meetup Slides
GraphQL Los Angeles Meetup Slides
 
Tk2323 lecture 9 api json
Tk2323 lecture 9   api jsonTk2323 lecture 9   api json
Tk2323 lecture 9 api json
 
RESTful API 제대로 만들기
RESTful API 제대로 만들기RESTful API 제대로 만들기
RESTful API 제대로 만들기
 
jSession #4 - Maciej Puchalski - Zaawansowany retrofit
jSession #4 - Maciej Puchalski - Zaawansowany retrofitjSession #4 - Maciej Puchalski - Zaawansowany retrofit
jSession #4 - Maciej Puchalski - Zaawansowany retrofit
 
Golang slidesaudrey
Golang slidesaudreyGolang slidesaudrey
Golang slidesaudrey
 
Semantic Web & TYPO3
Semantic Web & TYPO3Semantic Web & TYPO3
Semantic Web & TYPO3
 
Android and REST
Android and RESTAndroid and REST
Android and REST
 
Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss
 
David Gómez G. - Hypermedia APIs for headless platforms and Data Integration ...
David Gómez G. - Hypermedia APIs for headless platforms and Data Integration ...David Gómez G. - Hypermedia APIs for headless platforms and Data Integration ...
David Gómez G. - Hypermedia APIs for headless platforms and Data Integration ...
 
Cdm mil-18 - hypermedia ap is for headless platforms and data integration
Cdm mil-18 - hypermedia ap is for headless platforms and data integrationCdm mil-18 - hypermedia ap is for headless platforms and data integration
Cdm mil-18 - hypermedia ap is for headless platforms and data integration
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4
 
JSON and the APInauts
JSON and the APInautsJSON and the APInauts
JSON and the APInauts
 
Hypermedia APIs and HATEOAS / Wix Engineering
Hypermedia APIs and HATEOAS / Wix EngineeringHypermedia APIs and HATEOAS / Wix Engineering
Hypermedia APIs and HATEOAS / Wix Engineering
 
RESTful JSON web databases
RESTful JSON web databasesRESTful JSON web databases
RESTful JSON web databases
 
Specification-Driven Development of REST APIs by Alexander Zinchuk
Specification-Driven Development of REST APIs by Alexander Zinchuk   Specification-Driven Development of REST APIs by Alexander Zinchuk
Specification-Driven Development of REST APIs by Alexander Zinchuk
 
Example-driven Web API Specification Discovery
Example-driven Web API Specification DiscoveryExample-driven Web API Specification Discovery
Example-driven Web API Specification Discovery
 

Plus de Stormpath

How to Use Stormpath in angular js
How to Use Stormpath in angular jsHow to Use Stormpath in angular js
How to Use Stormpath in angular jsStormpath
 
Rest API Security
Rest API SecurityRest API Security
Rest API SecurityStormpath
 
Elegant Rest Design Webinar
Elegant Rest Design WebinarElegant Rest Design Webinar
Elegant Rest Design WebinarStormpath
 
Secure Your REST API (The Right Way)
Secure Your REST API (The Right Way)Secure Your REST API (The Right Way)
Secure Your REST API (The Right Way)Stormpath
 
Build a Node.js Client for Your REST+JSON API
Build a Node.js Client for Your REST+JSON APIBuild a Node.js Client for Your REST+JSON API
Build a Node.js Client for Your REST+JSON APIStormpath
 
Build A Killer Client For Your REST+JSON API
Build A Killer Client For Your REST+JSON APIBuild A Killer Client For Your REST+JSON API
Build A Killer Client For Your REST+JSON APIStormpath
 
REST API Design for JAX-RS And Jersey
REST API Design for JAX-RS And JerseyREST API Design for JAX-RS And Jersey
REST API Design for JAX-RS And JerseyStormpath
 

Plus de Stormpath (7)

How to Use Stormpath in angular js
How to Use Stormpath in angular jsHow to Use Stormpath in angular js
How to Use Stormpath in angular js
 
Rest API Security
Rest API SecurityRest API Security
Rest API Security
 
Elegant Rest Design Webinar
Elegant Rest Design WebinarElegant Rest Design Webinar
Elegant Rest Design Webinar
 
Secure Your REST API (The Right Way)
Secure Your REST API (The Right Way)Secure Your REST API (The Right Way)
Secure Your REST API (The Right Way)
 
Build a Node.js Client for Your REST+JSON API
Build a Node.js Client for Your REST+JSON APIBuild a Node.js Client for Your REST+JSON API
Build a Node.js Client for Your REST+JSON API
 
Build A Killer Client For Your REST+JSON API
Build A Killer Client For Your REST+JSON APIBuild A Killer Client For Your REST+JSON API
Build A Killer Client For Your REST+JSON API
 
REST API Design for JAX-RS And Jersey
REST API Design for JAX-RS And JerseyREST API Design for JAX-RS And Jersey
REST API Design for JAX-RS And Jersey
 

Dernier

DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Bhuvaneswari Subramani
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 

Dernier (20)

DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 

Building Beautiful REST APIs in ASP.NET Core

  • 1. BEAUTIFUL REST APIs in ASP.NET Core Nate Barbettini @nbarbettini recaffeinate.co .ws
  • 2. Overview ● Why is API design important? ● HATEOAS (Hypertext As The Engine Of Application State) ● REST APIs in ASP.NET Core
  • 3. /getAccount?id=17 Bad REST API design /getAccount?all=1&includePosts=1 /getAllAccounts /updateAccount?id=17 /createAccount /findPostsByAccountId?account=17 /accountSearch?lname=Skywalker /getAccount?id=17&includePosts=1 /getAccount?id=17&format=json /getAllAccountsJson /updateAccount?id=17&return=json /createAccountJson /accountSearch?lname=Skywalker&xml=1 /findPostsByAccountIdJSON?account=17 /getAllPosts?filter=account&id=17 /countAccounts /partialUpdateAccount?id=17 /getPostCount?id=17 /deleteUser
  • 4. HATEOAS, yo! "A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API). From that point on, all application state transitions must be driven by client selection of server-provided choices that are present in the received representations or implied by the user’s manipulation of those representations." ~ Dr. Fielding Tl;dr The API responses themselves should document what you are allowed to do and where you can go. If you can get to the root (/), you should be able to “travel” anywhere else in the API.
  • 5. Good REST API design should... ● Be discoverable and self-documenting ● Represent resources and collections ● Represent actions using HTTP verbs ● KISS!
  • 6. Revisiting the API example /users GET: List all users POST or PUT: Create a user /users/17 GET: Retrieve a single user POST or PUT: Update user details DELETE: Delete this user /users/17/posts GET: Get the user’s posts POST: Create a post /users?lname=Skywalker Search /users/17?include=posts Include linked data
  • 7. A specification for REST+JSON APIs The ION spec: https://github.com/ionwg/ion-doc
  • 8. Getting a single user GET /users/17 { "meta": { "href": "https://example.io/users/17" }, "firstName": "Luke", "lastName": "Skywalker" }
  • 9. Getting a list of users GET /users { "meta": { "href": "https://example.io/users", "rel": ["collection"] }, "items": [{ "meta": { "href": "https://example.io/users/17" }, "firstName": "Luke", "lastName": "Skywalker" }, { "meta": { "href": "https://example.io/users/18" }, "firstName": "Han", "lastName": "Solo" }] }
  • 10. Discoverable forms GET /users { ... "create": { "meta": { "href": "https://example.io/users", "rel": ["create-form"], "method": "post" }, "items": [ { "name": "firstName" }, { "name": "lastName" } ] } }
  • 11. Discoverable search GET /users { ... "search": { "meta": { "href": "https://example.io/users", "rel": ["search-form"], "method": "get" }, "items": [ { "name": "fname" }, { "name": "lname" } ] } }
  • 12. The starting point (API root) GET / { "meta": { "href": "https://example.io/" }, "users": { "meta": { "href": "https://example.io/users", "rel": ["collection"], } } }
  • 13. ● Install the .NET Core SDK - http://dot.net/core ● If you’re using Visual Studio: ○ Install the latest updates (Update 3) ○ Install the .NET Core tooling - https://go.microsoft.com/fwlink/?LinkID=824849 ● Or, install Visual Studio Code ● Create a new project from the ASP.NET Core (.NET Core) template ● Pick the API subtemplate ● Ready to run! Getting started with ASP.NET Core
  • 14. Getting a single user GET /users/17 { "meta": { "href": "https://example.io/users/17" }, "firstName": "Luke", "lastName": "Skywalker" }
  • 15. public class Link { public string Href { get; set; } } public abstract class Resource { [JsonProperty(Order = -2)] public Link Meta { get; set; } } Getting a single user
  • 16. public class User : Resource { public string FirstName { get; set; } public string LastName { get; set; } } Getting a single user
  • 17. [Route("/users")] public class UsersController : Controller { private readonly BulletinBoardDbContext _context; private readonly IUrlHelperFactory _urlHelperFactory; public UsersController( BulletinBoardDbContext context, IUrlHelperFactory urlHelperFactory) { _context = context; _urlHelperFactory = urlHelperFactory; } Getting a single user
  • 18. [Route("{id}")] public async Task<IActionResult> GetUser(string id) { var user = await _context.Users.SingleOrDefaultAsync(x => x.Id == id); if (user == null) return NotFound(); var urlHelper = _urlHelperFactory.GetUrlHelper(ControllerContext); var url = urlHelper.Link("default", new { controller = "users", id = user.Id }); var response = new User() { Meta = new Link() { Href = url }, FirstName = user.FirstName, LastName = user.LastName }; return Ok(response); } Getting a single user
  • 19. Getting a list of users GET /users { "meta": { "href": "https://example.io/users", "rel": ["collection"] }, "items": [{ "meta": { "href": "https://example.io/users/17" }, "firstName": "Luke", "lastName": "Skywalker" }, { "meta": { "href": "https://example.io/users/18" }, "firstName": "Han", "lastName": "Solo" }] }
  • 20. Getting a list of users public class Link { public string Href { get; set; } [JsonProperty(PropertyName = "rel", NullValueHandling = NullValueHandling.Ignore)] public string[] Relations { get; set; } }
  • 21. Getting a list of users public class Collection<T> : Resource { public T[] Items { get; set; } }
  • 22. Getting a list of users public async Task<IActionResult> GetAll() { var urlHelper = _urlHelperFactory.GetUrlHelper(ControllerContext); var allUsers = await _context.Users.ToArrayAsync(); var projected = allUsers.Select(x => new User() { Meta = new Link() { Href = urlHelper.Link("default", new { controller = "users", id = x.Id }) }, FirstName = x.FirstName, LastName = x.LastName }); var response = new Collection<User>() { Meta = new Link() { Href = urlHelper.Link("default", new { controller = "users" }), Relations = new string[] {"collection"}, }, Items = projected.ToArray() }; return Ok(response); }
  • 23. The starting point (API root) GET / { "meta": { "href": "https://example.io/" }, "users": { "meta": { "href": "https://example.io/users", "rel": ["collection"], } } }
  • 24. Adding a root route [Route("/")] public class RootController : Controller { private readonly IUrlHelperFactory _urlHelperFactory; public RootController(IUrlHelperFactory urlHelperFactory) { _urlHelperFactory = urlHelperFactory; } public IActionResult Get() { var urlHelper = _urlHelperFactory.GetUrlHelper(ControllerContext); var response = new { meta = new Link() { Href = urlHelper.Link("default", new { controller = "root" }) }, users = new Link() { Href = urlHelper.Link("default", new { controller = "users" }), Relations = new string[] {"collection"} } }; return Ok(response); } }
  • 25. Building and running (anywhere!) > dotnet build (...) Done. > dotnet run (...) Listening on https://localhost:5000
  • 26. Next Steps ● Full example https://github.com/nbarbettini/beautiful-rest-api-aspnetcore ● ION draft spec https://github.com/ionwg/ion-doc