SlideShare a Scribd company logo
1 of 82
Download to read offline
Hypermedia APIs for headless
platforms and Data Integration
David Gómez G.
@dgomezg
Why are APIs important?
One user, many devices, multiple apps
APIs enable multiple consumers
@dgomezg@liferayeng
Why do WE need APIs?
API
Backend
Frontends
Liferay APIs in 2018
SOAP-WS
JSONWS API
REST/JAX-RS
A Simple JAX-RS Service Endpoint.
@GET @Path("/blogs/{id}")
@Produces(APPLICATION_JSON)
public Response getBlogsEntry(long id) {
BlogsEntry blogsEntry = _blogsEntryService.getEntry(id);
return Response.ok(blogsEntry).build();
}
JAX-RS Service Building Blocks
‣ Application
‣ Resources
‣ Extensions
Application (Mandatory)
@Component
@ApplicationPath(“api")
public class RecipesApplication extends Application {
public Set<Class<?>> getSingletons() {
return Collections.singleton(new RecipeResource());
}
}
‣ Manages the API resources
@dgomezg@liferayeng
Resources
@Path("recipe")
public class RecipeResource {
@GET @Path("{id}")
public RecipeDTO retrieveRecipe(@PathParam("id") long id) {
return new RecipeDTO(_recipeService.getRecipe(id).getName());
}
@Reference
private RecipeService _recipeService;
}
‣ Manages the endpoints in a specific Path
Data Objects
@XmlRootElement
public class RecipeDTO {
@XmlElement
public List<String> getSteps() {
return steps;
}
@XmlElement
public long getId() {
return id;
}
‣ Annotated with binding info
Data Objects
public class RecipeDTO {
@JsonGetter(value = "steps")
public List<String> getSteps() {
return steps;
}
@JsonGetter(value = “id")
public long getId() {
return id;
}
‣ Annotated with binding info
Extensions
@PreMatching
public class AuthFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext ctx) throws IOException {
String authHeader = ctx.getHeaderString(HttpHeaders.AUTHORIZATION);
if (!verifyUser(authHeader)) {
throw new NotAuthorizedException("Not Authorized!");
}
}
private boolean verifyUser(String authHeader) {}
}
‣ Adds additional logic to the API
JAX-RS & OSGi
JAX-RS Whiteboard
‣ Aries JAX-RS whiteboard
‣ OSGi JAX-RS Whiteboard Specification RI
‣ Component-property based.
Thanks to @csierra & @rotty3000 !!!!
JAX-RS Whiteboard
‣ Component property based
@Component(
property = {
"osgi.jaxrs.application.select=(osgi.jaxrs.name=recipes-application)",
“osgi.jaxrs.resource=true"
},
service=Object.class)
@Path("recipe")
public class RecipeResource {
@GET @Path("{id}")
public RecipeDTO retrieveRecipe(@PathParam("id") long id) throws PortalException {
/* ... */
}
}
Plain JSON result
[
{
"address": {
"countryName": "united-states",
"regionName": "Alabama",
"street": "69108 Murphy Lights",
"zipCode": 11839
},
"chefId": 34212,
"id": 34203,
"logoURL": "/image/organization_logo?img_id=34209&t=1542808587173",
"name": "Chopping Victory"
}
]
Challenges of a Headless platform
Discoverable &
Documented
Consumption
Helpers
APIs Security
Mechanisms
Are we capable of
solving these
challenges?
Is REST still a valid
solution?
The Web is still a case of success
On the other side
REST style is an abstraction of
the architectural elements within
a distributed hypermedia system
-- Roy Fielding, 2000
Hypermedia Controls
Consumers must only know
ONE URL
And how to navigate from it
Contract with consumer defines
affordance types
(relations, actions, …)
Start with IANA’s 80 relation types
Home URL Link TypesAffordance Types
Home URL
$ curl -H "Accept: application/json-home" 
http://localhost:8080/o/api
{
"_links": {
"self": {
"href": "https://apiosample.wedeploy.io"
},
"blog-postings": {
"href": "https://apiosample.wedeploy.io/p/blog-postings"
},
"people": {
"href": "https://apiosample.wedeploy.io/p/people"
}
}
}
JSON-HOME
How to use it?
[
{
"address": {
"countryName": "united-states",
"regionName": "Alabama",
"street": "69108 Murphy Lights",
"zipCode": 11839
},
"chefId": 34212,
"id": 34203,
"logoURL": “...”,
"name": "Chopping Victory"
}
]
{

"_embedded": { /* Here, our RecipeDTO serialised in JSON */ },

"total": 43,

"count": 30,

"_links": {

"first": {

"href": "http://localhost:8080/o/api/p/person?page=1&per_page=30"

},

"next": {

"href": "http://localhost:8080/o/api/p/person?page=2&per_page=30"

},

"last": {

"href": "http://localhost:8080/o/api/p/person?page=2&per_page=30"

}

}

}
HAL
Pagination
Affordance Types
{

"_embedded": {/* Here, our RecipeDTO serialised in JSON */},

"total": 43,

"count": 30,

"_links": {

"first": {

"href": "http://localhost:8080/o/api/p/groups?page=1&per_page=30"

},

"next": {

"href": "http://localhost:8080/o/api/p/groups?page=2&per_page=30"

},

"last": {

"href": "http://localhost:8080/o/api/p/groups?page=2&per_page=30"

}

}

}
HAL
Pagination
Affordance Types
Defined by 

IANA Link Relations
Pagination
Affordance Types
{

"properties" : { /* Here, our RecipeDTO serialised in JSON */}, 

"actions": [

{

"name": "delete-item",

"title": "Delete recipe",

"method": "DELETE",

"href": "http://localhost:8080/o/p/recipe/abcdef",

}

{

"name": "publish",

"title": "Publish recipe",

"method": "POST",

"href": “http://localhost:8080/o/p/recipe/123URLs4123AREabcdeOPAQUEf",

}
…
Actions
SIREN
Affordance Types
{

..., 

"operation": [

{

"method": "DELETE",

"@id": "_:person/delete",

"@type": "Operation"

},

{

"expects": "http://localhost:8080/o/api/f/u/recipe",

"method": "PUT",

"@id": “_:recipe/update",

"@type": "Operation"

}

],
...
Actions
JSON+LD
Affordance Types
Operations
Affordance Types
Fields
{

...

"actions": [

{

"name": "add-recipe",

"title": "Add a new recipe",

"method": "POST",

"href": "http://localhost:8080/o/p/recipe",

"type": "application/json",

"fields": [

{ "name": “name", "type": "text" },

{ "name": "Chef", "type": "Person" },

]

}
…
SIREN
Affordance Types
{

..., 

"operation": [

{

"method": "DELETE",

"@id": "_:recipe/delete",

"@type": "Operation"

},

{

"expects": “http://localhost:8080/o/api/f/u/recipe",

"method": "PUT",

"@id": "_:recipe/update",

"@type": "Operation"

}

],
...
From Actions...
JSON+LD
Affordance Types
{

"@id": "http://localhost:8080/o/api/f/u/recipe",

"title": "The recipe updater form",

"description": "This form can be used to update a recipe",

"supportedProperty": [

{

"@type": "SupportedProperty",

"property": "alternateName",

"readable": false,

"required": false,

"writeable": true

},

{

"@type": "SupportedProperty",

"property": “password”,

"readable": false,

"required": true,

"writeable": true

},

...To Forms
JSON+LD
Affordance Types
Shared Vocabularies
Standard types
schema.org: 597 types y 867
properties
ActivityStreams, microformats,
…
Never expose internal models
Custom types must be
consumer focused
Well defined custom types
Schema.org
Inheritance-based
model
All attributes are
optional
Standard types
How to use it?
[
{
"address": {
"countryName": "united-states",
"regionName": "Alabama",
"street": "69108 Murphy Lights",
"zipCode": 11839
},
"chefId": 34212,
"id": 34203,
"logoURL": “...”,
"name": "Chopping Victory"
}
]
JSONWS API &
Plain JAX-RS
Richardson Maturity Model - Martin Fowler
Climbing the ladder easily
(Our recipes with Apio)
Apio Components
‣ Representor
‣ Actions
‣ Permisions
‣ Affordances
Representor Pattern
https://www.flickr.com/photos/xwl/4936781806/
Hypermedia formats
{

"gender": "female",

"familyName": "Hart",

"givenName": "Sophia",

"jobTitle": "Senior Executive",

"name": "Sophia Hart",

"alternateName": "sophia.hart",

"birthDate": "1965-04-12T00:00Z",

"email": "sophia.hart@example.com",

"_links": {

"self": {

"href": "http://host/o/api/p/people/30723"

}

}

}
{

"class": "BlogPosting",

"properties": {

"headline": "Hello DEVCON!",

"content": "The content of this blog posting"

},

"actions": [

{

"name": "delete-blog-posting",

"title": "Delete Blog Posting",

"method": "DELETE",

"href": "http://localhost:8080/o/p/blogs/32400"

}

],

"links": [

{

"rel": [ "self" ],

"href": "http://localhost:8080/o/p/blogs/32400"

},

]

}
{

"gender": "female",

"familyName": "Hart",

"givenName": "Sophia",

"jobTitle": "Senior Executive",

"name": "Sophia Hart",

"alternateName": "sophia.hart",

"birthDate": "1965-04-12T00:00Z",

"email": "sophia.hart@example.com",

"@id": "http://localhost:8080/o/api/p/people/30723",

"@type": [

"Person"

],

"@context": {

"@vocab": "http://schema.org"

}

}
SIREN
JSON+LD
HAL
Content Negotiation
Accept: application/ld+json
Content-Type: application/ld+json
Accept: application/vnd.siren+json
Content-Type: application/
vnd.siren+json
Accept: application/hal+json
Content-Type: application/
hal+json
Representor +
ContentNegotiation
Creating Types (I)
@Type(“Restaurant")
public interface RestaurantType extends Identifier<Long> {
@Id
public long getId();
@Field(“chefId”) @LinkedModel(PersonType.class)
public Long getChefId();
@Field("name")
public String getName();
@Field("logoUrl")
public String getLogoURL();
@Field("address")
public PostalAddressType getAddress();
}
Making DTO implement Types
@Type(“Restaurant")
public class OrganizationDTO implements RestaurantType {
}
And get rid of all those JAXB or Jackson annotations!!!
Representor Pattern
https://www.flickr.com/photos/xwl/4936781806/
With the Representor Pattern internal models are
transformed to types and stored as a generic
representation that can be then mapped
to the representation format chosen by the user
Apio Componentes
‣ Representor
‣ Actions
‣ Permisions
‣ Affordances
ActionRouter
@Component
public class RestaurantActionRouter implements ActionRouter<RestaurantType> {
@Retrieve
@EntryPoint
public List<RestaurantType> retrieve(User user) throws PortalException {
List<Organization> organizations =
_organizationService.getUserOrganizations(user.getUserId());
return organizations.stream()
.map(OrganizationDTO::new)
.collect(Collectors.toList());
}
}
Action (no URL mapping)EntryPoint
(appears in the Home URL)
ActionRouter
ActionRouter action annotations
import com.liferay.apio.architect.annotation.Actions.*;
@Create
@Remove
@Replace
@Retrieve
@EntryPoint
Method mapping annotations
@Remove
public void remove(@Id long id) {...}
@Id indicates an Identifier
@Body parses the body content
@Create
public BlogPostiong create(@Body BlogPosting blogPosting) {...}
@ParentId links to the Id of a parent resource
@Retrieve
public List<BlogPosting> retrieveBlogPosts(
@ParentId(Organization.class) long groupId)
Special context parameters
@Retrieve
public List<BlogPosting> retrieveBlogPosts(
@ParentId(Organization.class) long groupId, User user)
User extracted from Context, logged User
Pagination & PageItems to handle pagination
@EntryPoint @Retrieve
public PageItems<BlogPosting> retrievePage(Pagination pagination)
A more complex ActionRouter
@Component
public class BlogPostingActionRouter implements ActionRouter<BlogPosting> {
@Create
public BlogPosting create(@Body BlogPosting blogPosting) {...}
@Remove
public void remove(@Id long id) {...}
@Replace
public BlogPosting replace(@Id long id, @Body BlogPosting blogPosting) {...}
@Retrieve
public BlogPosting retrieve(@Id long id) {...}
@EntryPoint @Retrieve
public PageItems<BlogPosting> retrievePage(Pagination pagination) {return null;}
@Subscribe
public BlogSubscription subscribe(@Id long id, @Body BlogSubscription subscrption){...}
Resource embedding and Sparse field sets
http://localhost:8080/o/api/restaurant
?embedded=creator
&fields[Person]=name,image
&sort=datePublished:desc
&filter=name eq ‘Chopping Victory’
&page=1
&per_page=10
Search, Sort and filter (Affordances w URL templates)
http://localhost:8080/o/api/restaurant
?embedded=creator
&fields[Person]=name,image
&sort=datePublished:desc
&filter=name eq ‘Chopping Victory’
&page=1
&per_page=10
Pagination
http://localhost:8080/o/api/restaurant
?embedded=creator
&fields[Person]=name,image
&sort=datePublished:desc
&filter=name eq ‘Chopping Victory’
&page=1
&per_page=10
More out-of-the-box features
● Bean Validation (JSR 330) support
● Open API generated
● Discoverability from Home URL
● Vocabulary
Key scenarios
P a b l o A g u l l a
1
Backend of a
custom frontend
2
Enabler of
omnichannel
experiences
3
Data integration &
platform
management
P a b l o A g u l l a
3
Data integration &
platform
management
Data integration and platform administration
Other sources
Liferay JSON
schema
Headless APIs
Content Management API
Management
UI
Liferay Commerce
CRM
Navigability & auto-discovery
Final Lessons!|
Spend time defining your vocabulary
It is the most important design activity
for an API
Make consumers & their
developers the focus of your
API design strategy
● Provide features that make their job easier
● APIs should speak their language, not yours
Enable clients and tools to
discover and navigate your API
● Same code could work for different scenarios
Thanks
David Gómez G.
@dgomezg

More Related Content

What's hot

GraphQL - gdy API RESTowe to za mało
GraphQL - gdy API RESTowe to za małoGraphQL - gdy API RESTowe to za mało
GraphQL - gdy API RESTowe to za małoMarcinStachniuk
 
From CRUD to Hypermedia APIs with Spring
From CRUD to Hypermedia APIs with SpringFrom CRUD to Hypermedia APIs with Spring
From CRUD to Hypermedia APIs with SpringVladimir Tsukur
 
Building Awesome API with Spring
Building Awesome API with SpringBuilding Awesome API with Spring
Building Awesome API with SpringVladimir Tsukur
 
HATEOAS: The Confusing Bit from REST
HATEOAS: The Confusing Bit from RESTHATEOAS: The Confusing Bit from REST
HATEOAS: The Confusing Bit from RESTelliando dias
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedMarcinStachniuk
 
Building sustainable RESTFul services
Building sustainable RESTFul servicesBuilding sustainable RESTFul services
Building sustainable RESTFul servicesOrtus Solutions, Corp
 
SharePoint REST vs CSOM
SharePoint REST vs CSOMSharePoint REST vs CSOM
SharePoint REST vs CSOMMark Rackley
 
Beautiful REST+JSON APIs with Ion
Beautiful REST+JSON APIs with IonBeautiful REST+JSON APIs with Ion
Beautiful REST+JSON APIs with IonStormpath
 
Sigfox API Documentation
Sigfox API DocumentationSigfox API Documentation
Sigfox API DocumentationRod Hemphill
 
Design Beautiful REST + JSON APIs
Design Beautiful REST + JSON APIsDesign Beautiful REST + JSON APIs
Design Beautiful REST + JSON APIsStormpath
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreStormpath
 
Representational State Transfer (REST)
Representational State Transfer (REST)Representational State Transfer (REST)
Representational State Transfer (REST)David Krmpotic
 
Getting into ember.js
Getting into ember.jsGetting into ember.js
Getting into ember.jsreybango
 
The REST And Then Some
The REST And Then SomeThe REST And Then Some
The REST And Then SomeNordic APIs
 
Cross-Platform Data Access for Android and iPhone
Cross-Platform Data Access for Android and iPhoneCross-Platform Data Access for Android and iPhone
Cross-Platform Data Access for Android and iPhonePeter Friese
 
RESTful Architecture
RESTful ArchitectureRESTful Architecture
RESTful ArchitectureKabir Baidya
 
Javascript Frameworks for Well Architected, Immersive Web Apps
Javascript Frameworks for Well Architected, Immersive Web AppsJavascript Frameworks for Well Architected, Immersive Web Apps
Javascript Frameworks for Well Architected, Immersive Web Appsdnelson-cs
 

What's hot (20)

GraphQL - gdy API RESTowe to za mało
GraphQL - gdy API RESTowe to za małoGraphQL - gdy API RESTowe to za mało
GraphQL - gdy API RESTowe to za mało
 
From CRUD to Hypermedia APIs with Spring
From CRUD to Hypermedia APIs with SpringFrom CRUD to Hypermedia APIs with Spring
From CRUD to Hypermedia APIs with Spring
 
Building Awesome API with Spring
Building Awesome API with SpringBuilding Awesome API with Spring
Building Awesome API with Spring
 
HATEOAS: The Confusing Bit from REST
HATEOAS: The Confusing Bit from RESTHATEOAS: The Confusing Bit from REST
HATEOAS: The Confusing Bit from REST
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learned
 
Building sustainable RESTFul services
Building sustainable RESTFul servicesBuilding sustainable RESTFul services
Building sustainable RESTFul services
 
API Design Tour: Dell
API Design Tour: DellAPI Design Tour: Dell
API Design Tour: Dell
 
SharePoint REST vs CSOM
SharePoint REST vs CSOMSharePoint REST vs CSOM
SharePoint REST vs CSOM
 
Beautiful REST+JSON APIs with Ion
Beautiful REST+JSON APIs with IonBeautiful REST+JSON APIs with Ion
Beautiful REST+JSON APIs with Ion
 
Sigfox API Documentation
Sigfox API DocumentationSigfox API Documentation
Sigfox API Documentation
 
Design Beautiful REST + JSON APIs
Design Beautiful REST + JSON APIsDesign Beautiful REST + JSON APIs
Design Beautiful REST + JSON APIs
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET Core
 
Representational State Transfer (REST)
Representational State Transfer (REST)Representational State Transfer (REST)
Representational State Transfer (REST)
 
Getting into ember.js
Getting into ember.jsGetting into ember.js
Getting into ember.js
 
Rest API
Rest APIRest API
Rest API
 
The REST And Then Some
The REST And Then SomeThe REST And Then Some
The REST And Then Some
 
Cross-Platform Data Access for Android and iPhone
Cross-Platform Data Access for Android and iPhoneCross-Platform Data Access for Android and iPhone
Cross-Platform Data Access for Android and iPhone
 
RESTful Architecture
RESTful ArchitectureRESTful Architecture
RESTful Architecture
 
Javascript Frameworks for Well Architected, Immersive Web Apps
Javascript Frameworks for Well Architected, Immersive Web AppsJavascript Frameworks for Well Architected, Immersive Web Apps
Javascript Frameworks for Well Architected, Immersive Web Apps
 
Rest and Rails
Rest and RailsRest and Rails
Rest and Rails
 

Similar to Hypermedia APIs for headless platforms

The liferay case: lessons learned evolving from RPC to Hypermedia REST APIs
The liferay case: lessons learned evolving from RPC to Hypermedia REST APIsThe liferay case: lessons learned evolving from RPC to Hypermedia REST APIs
The liferay case: lessons learned evolving from RPC to Hypermedia REST APIsJorge Ferrer
 
Introduction to GraphQL and AWS Appsync on AWS - iOS
Introduction to GraphQL and AWS Appsync on AWS - iOSIntroduction to GraphQL and AWS Appsync on AWS - iOS
Introduction to GraphQL and AWS Appsync on AWS - iOSAmazon Web Services
 
APIs, Web Services, and Mashups: What they are and how they can be used
APIs, Web Services, and Mashups: What they are and how they can be usedAPIs, Web Services, and Mashups: What they are and how they can be used
APIs, Web Services, and Mashups: What they are and how they can be usedsnackeru
 
Ibm_interconnect_restapi_workshop
Ibm_interconnect_restapi_workshopIbm_interconnect_restapi_workshop
Ibm_interconnect_restapi_workshopShubhra Kar
 
Java Script Based Client Server Webapps 2
Java Script Based Client Server Webapps 2Java Script Based Client Server Webapps 2
Java Script Based Client Server Webapps 2kriszyp
 
RESTful Web APIs – Mike Amundsen, Principal API Architect, Layer 7
RESTful Web APIs – Mike Amundsen, Principal API Architect, Layer 7RESTful Web APIs – Mike Amundsen, Principal API Architect, Layer 7
RESTful Web APIs – Mike Amundsen, Principal API Architect, Layer 7CA API Management
 
Building APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformBuilding APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformAntonio Peric-Mazar
 
How APIs Can Be Secured in Mobile Environments
How APIs Can Be Secured in Mobile EnvironmentsHow APIs Can Be Secured in Mobile Environments
How APIs Can Be Secured in Mobile EnvironmentsWSO2
 
Vital AI MetaQL: Queries Across NoSQL, SQL, Sparql, and Spark
Vital AI MetaQL: Queries Across NoSQL, SQL, Sparql, and SparkVital AI MetaQL: Queries Across NoSQL, SQL, Sparql, and Spark
Vital AI MetaQL: Queries Across NoSQL, SQL, Sparql, and SparkVital.AI
 
Supercharging Applications with GraphQL and AWS AppSync
Supercharging Applications with GraphQL and AWS AppSyncSupercharging Applications with GraphQL and AWS AppSync
Supercharging Applications with GraphQL and AWS AppSyncAmazon Web Services
 
apidays LIVE New York - API Code First vs Design First by Phil Sturgeon
apidays LIVE New York - API Code First vs Design First by Phil Sturgeonapidays LIVE New York - API Code First vs Design First by Phil Sturgeon
apidays LIVE New York - API Code First vs Design First by Phil Sturgeonapidays
 
Develop iOS and Android apps with SharePoint/Office 365
Develop iOS and Android apps with SharePoint/Office 365Develop iOS and Android apps with SharePoint/Office 365
Develop iOS and Android apps with SharePoint/Office 365Kashif Imran
 
Take Mobile and Web Apps to the Next Level with AWS AppSync and AWS Amplify
Take Mobile and Web Apps to the Next Level with AWS AppSync and AWS Amplify Take Mobile and Web Apps to the Next Level with AWS AppSync and AWS Amplify
Take Mobile and Web Apps to the Next Level with AWS AppSync and AWS Amplify Amazon Web Services
 
ICONUK 2016: REST Assured, Freeing Your Domino Data Has Never Been That Easy!
ICONUK 2016: REST Assured, Freeing Your Domino Data Has Never Been That Easy!ICONUK 2016: REST Assured, Freeing Your Domino Data Has Never Been That Easy!
ICONUK 2016: REST Assured, Freeing Your Domino Data Has Never Been That Easy!Serdar Basegmez
 
aip-workshop1-dev-tutorial
aip-workshop1-dev-tutorialaip-workshop1-dev-tutorial
aip-workshop1-dev-tutorialMatthew Vaughn
 

Similar to Hypermedia APIs for headless platforms (20)

The liferay case: lessons learned evolving from RPC to Hypermedia REST APIs
The liferay case: lessons learned evolving from RPC to Hypermedia REST APIsThe liferay case: lessons learned evolving from RPC to Hypermedia REST APIs
The liferay case: lessons learned evolving from RPC to Hypermedia REST APIs
 
Introduction to GraphQL and AWS Appsync on AWS - iOS
Introduction to GraphQL and AWS Appsync on AWS - iOSIntroduction to GraphQL and AWS Appsync on AWS - iOS
Introduction to GraphQL and AWS Appsync on AWS - iOS
 
The Glory of Rest
The Glory of RestThe Glory of Rest
The Glory of Rest
 
Switch to Backend 2023
Switch to Backend 2023Switch to Backend 2023
Switch to Backend 2023
 
APIs, Web Services, and Mashups: What they are and how they can be used
APIs, Web Services, and Mashups: What they are and how they can be usedAPIs, Web Services, and Mashups: What they are and how they can be used
APIs, Web Services, and Mashups: What they are and how they can be used
 
REST easy with API Platform
REST easy with API PlatformREST easy with API Platform
REST easy with API Platform
 
Ibm_interconnect_restapi_workshop
Ibm_interconnect_restapi_workshopIbm_interconnect_restapi_workshop
Ibm_interconnect_restapi_workshop
 
AppSync and GraphQL on iOS
AppSync and GraphQL on iOSAppSync and GraphQL on iOS
AppSync and GraphQL on iOS
 
Java Script Based Client Server Webapps 2
Java Script Based Client Server Webapps 2Java Script Based Client Server Webapps 2
Java Script Based Client Server Webapps 2
 
RESTful Web APIs – Mike Amundsen, Principal API Architect, Layer 7
RESTful Web APIs – Mike Amundsen, Principal API Architect, Layer 7RESTful Web APIs – Mike Amundsen, Principal API Architect, Layer 7
RESTful Web APIs – Mike Amundsen, Principal API Architect, Layer 7
 
Building APIs in an easy way using API Platform
Building APIs in an easy way using API PlatformBuilding APIs in an easy way using API Platform
Building APIs in an easy way using API Platform
 
How APIs Can Be Secured in Mobile Environments
How APIs Can Be Secured in Mobile EnvironmentsHow APIs Can Be Secured in Mobile Environments
How APIs Can Be Secured in Mobile Environments
 
Vital AI MetaQL: Queries Across NoSQL, SQL, Sparql, and Spark
Vital AI MetaQL: Queries Across NoSQL, SQL, Sparql, and SparkVital AI MetaQL: Queries Across NoSQL, SQL, Sparql, and Spark
Vital AI MetaQL: Queries Across NoSQL, SQL, Sparql, and Spark
 
Supercharging Applications with GraphQL and AWS AppSync
Supercharging Applications with GraphQL and AWS AppSyncSupercharging Applications with GraphQL and AWS AppSync
Supercharging Applications with GraphQL and AWS AppSync
 
apidays LIVE New York - API Code First vs Design First by Phil Sturgeon
apidays LIVE New York - API Code First vs Design First by Phil Sturgeonapidays LIVE New York - API Code First vs Design First by Phil Sturgeon
apidays LIVE New York - API Code First vs Design First by Phil Sturgeon
 
Hi5 Open Social
Hi5   Open SocialHi5   Open Social
Hi5 Open Social
 
Develop iOS and Android apps with SharePoint/Office 365
Develop iOS and Android apps with SharePoint/Office 365Develop iOS and Android apps with SharePoint/Office 365
Develop iOS and Android apps with SharePoint/Office 365
 
Take Mobile and Web Apps to the Next Level with AWS AppSync and AWS Amplify
Take Mobile and Web Apps to the Next Level with AWS AppSync and AWS Amplify Take Mobile and Web Apps to the Next Level with AWS AppSync and AWS Amplify
Take Mobile and Web Apps to the Next Level with AWS AppSync and AWS Amplify
 
ICONUK 2016: REST Assured, Freeing Your Domino Data Has Never Been That Easy!
ICONUK 2016: REST Assured, Freeing Your Domino Data Has Never Been That Easy!ICONUK 2016: REST Assured, Freeing Your Domino Data Has Never Been That Easy!
ICONUK 2016: REST Assured, Freeing Your Domino Data Has Never Been That Easy!
 
aip-workshop1-dev-tutorial
aip-workshop1-dev-tutorialaip-workshop1-dev-tutorial
aip-workshop1-dev-tutorial
 

More from Codemotion

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Codemotion
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyCodemotion
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaCodemotion
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserCodemotion
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Codemotion
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Codemotion
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Codemotion
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 - Codemotion
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Codemotion
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Codemotion
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Codemotion
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Codemotion
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Codemotion
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Codemotion
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Codemotion
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...Codemotion
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Codemotion
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Codemotion
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Codemotion
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Codemotion
 

More from Codemotion (20)

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending story
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storia
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard Altwasser
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
 

Recently uploaded

Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Hyundai Motor Group
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 

Recently uploaded (20)

Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 

Hypermedia APIs for headless platforms

  • 1. Hypermedia APIs for headless platforms and Data Integration David Gómez G. @dgomezg
  • 2. Why are APIs important?
  • 3.
  • 4. One user, many devices, multiple apps
  • 5. APIs enable multiple consumers @dgomezg@liferayeng
  • 6. Why do WE need APIs?
  • 7.
  • 8.
  • 11.
  • 12.
  • 13.
  • 18. A Simple JAX-RS Service Endpoint. @GET @Path("/blogs/{id}") @Produces(APPLICATION_JSON) public Response getBlogsEntry(long id) { BlogsEntry blogsEntry = _blogsEntryService.getEntry(id); return Response.ok(blogsEntry).build(); }
  • 19. JAX-RS Service Building Blocks ‣ Application ‣ Resources ‣ Extensions
  • 20. Application (Mandatory) @Component @ApplicationPath(“api") public class RecipesApplication extends Application { public Set<Class<?>> getSingletons() { return Collections.singleton(new RecipeResource()); } } ‣ Manages the API resources @dgomezg@liferayeng
  • 21. Resources @Path("recipe") public class RecipeResource { @GET @Path("{id}") public RecipeDTO retrieveRecipe(@PathParam("id") long id) { return new RecipeDTO(_recipeService.getRecipe(id).getName()); } @Reference private RecipeService _recipeService; } ‣ Manages the endpoints in a specific Path
  • 22. Data Objects @XmlRootElement public class RecipeDTO { @XmlElement public List<String> getSteps() { return steps; } @XmlElement public long getId() { return id; } ‣ Annotated with binding info
  • 23. Data Objects public class RecipeDTO { @JsonGetter(value = "steps") public List<String> getSteps() { return steps; } @JsonGetter(value = “id") public long getId() { return id; } ‣ Annotated with binding info
  • 24. Extensions @PreMatching public class AuthFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext ctx) throws IOException { String authHeader = ctx.getHeaderString(HttpHeaders.AUTHORIZATION); if (!verifyUser(authHeader)) { throw new NotAuthorizedException("Not Authorized!"); } } private boolean verifyUser(String authHeader) {} } ‣ Adds additional logic to the API
  • 26. JAX-RS Whiteboard ‣ Aries JAX-RS whiteboard ‣ OSGi JAX-RS Whiteboard Specification RI ‣ Component-property based. Thanks to @csierra & @rotty3000 !!!!
  • 27. JAX-RS Whiteboard ‣ Component property based @Component( property = { "osgi.jaxrs.application.select=(osgi.jaxrs.name=recipes-application)", “osgi.jaxrs.resource=true" }, service=Object.class) @Path("recipe") public class RecipeResource { @GET @Path("{id}") public RecipeDTO retrieveRecipe(@PathParam("id") long id) throws PortalException { /* ... */ } }
  • 28. Plain JSON result [ { "address": { "countryName": "united-states", "regionName": "Alabama", "street": "69108 Murphy Lights", "zipCode": 11839 }, "chefId": 34212, "id": 34203, "logoURL": "/image/organization_logo?img_id=34209&t=1542808587173", "name": "Chopping Victory" } ]
  • 29. Challenges of a Headless platform Discoverable & Documented Consumption Helpers APIs Security Mechanisms
  • 30. Are we capable of solving these challenges?
  • 31. Is REST still a valid solution?
  • 32. The Web is still a case of success On the other side
  • 33. REST style is an abstraction of the architectural elements within a distributed hypermedia system -- Roy Fielding, 2000
  • 34.
  • 35. Hypermedia Controls Consumers must only know ONE URL And how to navigate from it Contract with consumer defines affordance types (relations, actions, …) Start with IANA’s 80 relation types Home URL Link TypesAffordance Types
  • 36. Home URL $ curl -H "Accept: application/json-home" http://localhost:8080/o/api { "_links": { "self": { "href": "https://apiosample.wedeploy.io" }, "blog-postings": { "href": "https://apiosample.wedeploy.io/p/blog-postings" }, "people": { "href": "https://apiosample.wedeploy.io/p/people" } } } JSON-HOME
  • 37. How to use it? [ { "address": { "countryName": "united-states", "regionName": "Alabama", "street": "69108 Murphy Lights", "zipCode": 11839 }, "chefId": 34212, "id": 34203, "logoURL": “...”, "name": "Chopping Victory" } ]
  • 38. {
 "_embedded": { /* Here, our RecipeDTO serialised in JSON */ },
 "total": 43,
 "count": 30,
 "_links": {
 "first": {
 "href": "http://localhost:8080/o/api/p/person?page=1&per_page=30"
 },
 "next": {
 "href": "http://localhost:8080/o/api/p/person?page=2&per_page=30"
 },
 "last": {
 "href": "http://localhost:8080/o/api/p/person?page=2&per_page=30"
 }
 }
 } HAL Pagination Affordance Types
  • 39. {
 "_embedded": {/* Here, our RecipeDTO serialised in JSON */},
 "total": 43,
 "count": 30,
 "_links": {
 "first": {
 "href": "http://localhost:8080/o/api/p/groups?page=1&per_page=30"
 },
 "next": {
 "href": "http://localhost:8080/o/api/p/groups?page=2&per_page=30"
 },
 "last": {
 "href": "http://localhost:8080/o/api/p/groups?page=2&per_page=30"
 }
 }
 } HAL Pagination Affordance Types Defined by 
 IANA Link Relations
  • 41. {
 "properties" : { /* Here, our RecipeDTO serialised in JSON */}, 
 "actions": [
 {
 "name": "delete-item",
 "title": "Delete recipe",
 "method": "DELETE",
 "href": "http://localhost:8080/o/p/recipe/abcdef",
 }
 {
 "name": "publish",
 "title": "Publish recipe",
 "method": "POST",
 "href": “http://localhost:8080/o/p/recipe/123URLs4123AREabcdeOPAQUEf",
 } … Actions SIREN Affordance Types
  • 42. {
 ..., 
 "operation": [
 {
 "method": "DELETE",
 "@id": "_:person/delete",
 "@type": "Operation"
 },
 {
 "expects": "http://localhost:8080/o/api/f/u/recipe",
 "method": "PUT",
 "@id": “_:recipe/update",
 "@type": "Operation"
 }
 ], ... Actions JSON+LD Affordance Types
  • 44. Fields {
 ...
 "actions": [
 {
 "name": "add-recipe",
 "title": "Add a new recipe",
 "method": "POST",
 "href": "http://localhost:8080/o/p/recipe",
 "type": "application/json",
 "fields": [
 { "name": “name", "type": "text" },
 { "name": "Chef", "type": "Person" },
 ]
 } … SIREN Affordance Types
  • 45. {
 ..., 
 "operation": [
 {
 "method": "DELETE",
 "@id": "_:recipe/delete",
 "@type": "Operation"
 },
 {
 "expects": “http://localhost:8080/o/api/f/u/recipe",
 "method": "PUT",
 "@id": "_:recipe/update",
 "@type": "Operation"
 }
 ], ... From Actions... JSON+LD Affordance Types
  • 46. {
 "@id": "http://localhost:8080/o/api/f/u/recipe",
 "title": "The recipe updater form",
 "description": "This form can be used to update a recipe",
 "supportedProperty": [
 {
 "@type": "SupportedProperty",
 "property": "alternateName",
 "readable": false,
 "required": false,
 "writeable": true
 },
 {
 "@type": "SupportedProperty",
 "property": “password”,
 "readable": false,
 "required": true,
 "writeable": true
 },
 ...To Forms JSON+LD Affordance Types
  • 47. Shared Vocabularies Standard types schema.org: 597 types y 867 properties ActivityStreams, microformats, … Never expose internal models Custom types must be consumer focused Well defined custom types
  • 49. How to use it? [ { "address": { "countryName": "united-states", "regionName": "Alabama", "street": "69108 Murphy Lights", "zipCode": 11839 }, "chefId": 34212, "id": 34203, "logoURL": “...”, "name": "Chopping Victory" } ]
  • 50. JSONWS API & Plain JAX-RS Richardson Maturity Model - Martin Fowler
  • 51. Climbing the ladder easily (Our recipes with Apio)
  • 52. Apio Components ‣ Representor ‣ Actions ‣ Permisions ‣ Affordances
  • 54. Hypermedia formats {
 "gender": "female",
 "familyName": "Hart",
 "givenName": "Sophia",
 "jobTitle": "Senior Executive",
 "name": "Sophia Hart",
 "alternateName": "sophia.hart",
 "birthDate": "1965-04-12T00:00Z",
 "email": "sophia.hart@example.com",
 "_links": {
 "self": {
 "href": "http://host/o/api/p/people/30723"
 }
 }
 } {
 "class": "BlogPosting",
 "properties": {
 "headline": "Hello DEVCON!",
 "content": "The content of this blog posting"
 },
 "actions": [
 {
 "name": "delete-blog-posting",
 "title": "Delete Blog Posting",
 "method": "DELETE",
 "href": "http://localhost:8080/o/p/blogs/32400"
 }
 ],
 "links": [
 {
 "rel": [ "self" ],
 "href": "http://localhost:8080/o/p/blogs/32400"
 },
 ]
 } {
 "gender": "female",
 "familyName": "Hart",
 "givenName": "Sophia",
 "jobTitle": "Senior Executive",
 "name": "Sophia Hart",
 "alternateName": "sophia.hart",
 "birthDate": "1965-04-12T00:00Z",
 "email": "sophia.hart@example.com",
 "@id": "http://localhost:8080/o/api/p/people/30723",
 "@type": [
 "Person"
 ],
 "@context": {
 "@vocab": "http://schema.org"
 }
 } SIREN JSON+LD HAL
  • 55. Content Negotiation Accept: application/ld+json Content-Type: application/ld+json Accept: application/vnd.siren+json Content-Type: application/ vnd.siren+json Accept: application/hal+json Content-Type: application/ hal+json Representor + ContentNegotiation
  • 56. Creating Types (I) @Type(“Restaurant") public interface RestaurantType extends Identifier<Long> { @Id public long getId(); @Field(“chefId”) @LinkedModel(PersonType.class) public Long getChefId(); @Field("name") public String getName(); @Field("logoUrl") public String getLogoURL(); @Field("address") public PostalAddressType getAddress(); }
  • 57. Making DTO implement Types @Type(“Restaurant") public class OrganizationDTO implements RestaurantType { } And get rid of all those JAXB or Jackson annotations!!!
  • 58. Representor Pattern https://www.flickr.com/photos/xwl/4936781806/ With the Representor Pattern internal models are transformed to types and stored as a generic representation that can be then mapped to the representation format chosen by the user
  • 59. Apio Componentes ‣ Representor ‣ Actions ‣ Permisions ‣ Affordances
  • 60. ActionRouter @Component public class RestaurantActionRouter implements ActionRouter<RestaurantType> { @Retrieve @EntryPoint public List<RestaurantType> retrieve(User user) throws PortalException { List<Organization> organizations = _organizationService.getUserOrganizations(user.getUserId()); return organizations.stream() .map(OrganizationDTO::new) .collect(Collectors.toList()); } } Action (no URL mapping)EntryPoint (appears in the Home URL) ActionRouter
  • 61. ActionRouter action annotations import com.liferay.apio.architect.annotation.Actions.*; @Create @Remove @Replace @Retrieve @EntryPoint
  • 62. Method mapping annotations @Remove public void remove(@Id long id) {...} @Id indicates an Identifier @Body parses the body content @Create public BlogPostiong create(@Body BlogPosting blogPosting) {...} @ParentId links to the Id of a parent resource @Retrieve public List<BlogPosting> retrieveBlogPosts( @ParentId(Organization.class) long groupId)
  • 63. Special context parameters @Retrieve public List<BlogPosting> retrieveBlogPosts( @ParentId(Organization.class) long groupId, User user) User extracted from Context, logged User Pagination & PageItems to handle pagination @EntryPoint @Retrieve public PageItems<BlogPosting> retrievePage(Pagination pagination)
  • 64. A more complex ActionRouter @Component public class BlogPostingActionRouter implements ActionRouter<BlogPosting> { @Create public BlogPosting create(@Body BlogPosting blogPosting) {...} @Remove public void remove(@Id long id) {...} @Replace public BlogPosting replace(@Id long id, @Body BlogPosting blogPosting) {...} @Retrieve public BlogPosting retrieve(@Id long id) {...} @EntryPoint @Retrieve public PageItems<BlogPosting> retrievePage(Pagination pagination) {return null;} @Subscribe public BlogSubscription subscribe(@Id long id, @Body BlogSubscription subscrption){...}
  • 65. Resource embedding and Sparse field sets http://localhost:8080/o/api/restaurant ?embedded=creator &fields[Person]=name,image &sort=datePublished:desc &filter=name eq ‘Chopping Victory’ &page=1 &per_page=10
  • 66. Search, Sort and filter (Affordances w URL templates) http://localhost:8080/o/api/restaurant ?embedded=creator &fields[Person]=name,image &sort=datePublished:desc &filter=name eq ‘Chopping Victory’ &page=1 &per_page=10
  • 68. More out-of-the-box features ● Bean Validation (JSR 330) support ● Open API generated ● Discoverability from Home URL ● Vocabulary
  • 70. P a b l o A g u l l a 1 Backend of a custom frontend 2 Enabler of omnichannel experiences 3 Data integration & platform management
  • 71. P a b l o A g u l l a 3 Data integration & platform management
  • 72. Data integration and platform administration Other sources Liferay JSON schema Headless APIs Content Management API Management UI Liferay Commerce CRM
  • 73.
  • 74.
  • 75.
  • 76.
  • 79. Spend time defining your vocabulary It is the most important design activity for an API
  • 80. Make consumers & their developers the focus of your API design strategy ● Provide features that make their job easier ● APIs should speak their language, not yours
  • 81. Enable clients and tools to discover and navigate your API ● Same code could work for different scenarios