+ All Categories
Home > Documents > The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration...

The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration...

Date post: 24-Apr-2020
Category:
Upload: others
View: 15 times
Download: 0 times
Share this document with a friend
90
The Liferay case Lessons learned evolving from RPC to Hypermedia REST APIs
Transcript
Page 1: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

The Liferay caseLessons learned evolving from RPC to Hypermedia REST APIs

Page 2: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

This slides are already available at

bit.ly/liferay-hypermedia-api

Page 3: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Who are we?

VP of Engineering|

Jorge Ferrer|

Software Engineer|

Alejandro Hernández|

Page 4: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Why do we need APIs?

Page 5: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Liferay is a software provider

Open Source APIsOn-Premise + Cloud

Digital Experiences Web, Mobile, ...Platform

Page 6: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Key usages of APIs in Liferay

1 Integration

Omni-channel consumers

Web Applications

2

3

Page 7: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

The beginnings: SOAP|

Page 8: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Conclusions - The Good

Enabled the possibility of integration with external systems

Easy to build APIs thanks to code generation from Java APIs

Page 9: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Conclusions - The Ugly

Compatibility problems✘

Hard to consume APIs

Strong dependency on tooling

⇒ Poor adoption

Page 10: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Next step: REST-API|

Page 11: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

REST-API“ ”

mmm….

We mean RPC over HTTP

Page 12: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

“REST”-API: JSON Web Services

● Automatic generation of an HTTP+JSON Web API from a Java API

● Auto-generated interactive documentation● Batch operations

Page 13: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

We were here

Richardson Maturity Model - Martin Fowler

Is that bad?

Page 14: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Conclusions - The Good

Very comprehensive , 90+% of the platform’s functionalities

More developer friendly

Interactive docs, batch operations, ... were highly appreciated ⇒ More adoption

Page 15: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Conclusions - The Ugly (1/2)

Certain APIs were very difficult to consume●

✘ Custom technology. Requires learning just for Liferay

Page 16: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Conclusions - The Ugly (2/2)

Internal changes auto-propagated ⇒ Consumers were broken in every release●

✘ Increasingly perceived as bad/old API in comparison●

Page 17: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

We also tried a “competing” approach!

● AtomPub (With Shindig)○ Fully RESTful○ Atom XML

● Mapping Layer○ Manual Coding

Page 18: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Lessons!|

Page 19: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Lessons

1. API generation means✓ Less work and more comprehensiveness✘ Deep coupling

2. Importance of features for consumer devs

Page 20: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

In search of a better solution

Page 21: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Our two key challenges

Developer Experience

Change Management

Evolution

Page 22: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Consumer?

API v3API v1 API v2 API v4

Page 23: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

The cost of breaking changes

For consumer devs

● Being forced to change code with each new version

For API devs

● Visible: Keep several API versions alive

● Hidden: Avoid change to reduce visible cost

Page 24: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Are we really the only ones with this problem?

Page 25: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

How should APIs be versioned?

Page 26: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Is hypermedia really feasible or is it a utopia?

Page 27: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

What is the *best* format for the API responses?

JSON or XML?

Or should it be binary?

HAL, JSON-LD, Siren, JSON-API, …?

Page 28: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Is REST dead and should we go with GraphQL?

Page 29: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Learning from the best

1. The most popular “API Guidelines”

2. Tons of articles and several books.

Page 30: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Books that made a

difference for us

Page 31: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Our solution

Page 32: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs
Page 33: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

APIs designed to evolveHow we are solving each of the challenges

Page 34: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

1. Hypermedia Controls

Home URL Link TypesAffordance Types

Page 35: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Pagination

Page 36: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

{ "_embedded": {...}, "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

Page 37: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

{ “properties”: { “title”: “Hypermedia is awesome”, … }   "actions": [       {           "name": "delete-item",           "title": "Delete Blog Posting",           "method": "DELETE",           "href": "http://localhost:8080/o/p/blogs/abcdef",       }       {           "name": "publish",           "title": "Publish Blog Posting",           "method": "POST",           "href": "http://localhost:8080/o/p/123URLs4123AREabcdeOPAQUEf41231",       } …

Actions

SIREN

Page 38: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Forms{   ..   "actions": [       {           "name": "add-blog-posting",           "title": "Add Blog Posting",           "method": "POST",           "href": "http://localhost:8080/o/p/blogs",           "type": "application/json",           "fields": [               { "name": "headline", "type": "text" },               { "name": "author", "type": "Person" },           ]       }   …

SIREN

Page 39: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

2. Shared Vocabularies

Standard types Well defined custom types

Page 40: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Internal

Page 41: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Schema.org type

Page 42: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Defining types

most important API design activity

Page 43: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Communicating the types

OpenAPI JSON Schema ALPS

Profile ⇒

Page 44: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Goal: The smallest contract possible

● One single URL● Message types● Affordance types

Page 45: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs
Page 46: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs
Page 47: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Building Consumers

1

2

3

Page 48: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

How should APIs be versioned?

Page 49: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Is hypermedia really feasible or is it a utopia?

Page 50: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

What is the *best* format for the API responses?

Page 51: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Is REST dead and should we go with GraphQL?

Page 52: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Does this work for real?

Page 53: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Project: Microservice APIsAPI stack: Java with SpringConsumers: Java Microservice, Mobile App 1

Page 54: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Home URL

{name: "pulpo-api",description: "API for consuming PULPO Services",_links: {

self: { href: "http://localhost:8084/" },accounts: {

href: "localhost/{projectId}/accounts{?filter,page,size,sort*}",templated: true

},account: {

href: "localhost/{projectId}/accounts/{identifier}",templated: true

},fields: {

href: "localhost/{projectId}/fields{?filter,page,size,sort*}",templated: true

},field: {

href: "localhost/{projectId}/fields/{identifier}",templated: true

},}

}HAL

Page 55: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs
Page 56: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

{"dateCreated":"2017-11-15T16:23:35Z","dateModified":"2017-11-15T16:23:35Z","identifier":"AV_Afi6-Y3UMLZEdmkBE","name":"Friends","segmentType":"STATIC","status":"ACTIVE","_links":{

"self":{"href":"http://localhost:8084/my-project/individual-segments/AV_Afi6-Y3UMLZEdmkBE"

},"individual-segments":{

"href":"http://localhost:8084/my-project/individual-segments{?filter}","templated":true

}}

}

HAL

Affordance Types

Page 57: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

internal

Page 58: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

@GetMapping(produces = {MediaType.APPLICATION_JSON_VALUE, "application/hal+json"},value = "/{identifier}"

)public @ResponseBody Resource<Individual> findOne(

@PathVariable String projectId, @PathVariable String identifier) {

IndividualEntity individualEntity = _individualService.findOneByUUID(projectId, identifier);

if (individualEntity == null) {throw new NotFoundException(

"Unable to find Individual with individualUUID " + identifier);}

return _individualResourceAssembler.toResource(individualEntity);}

Affordance Types

Page 59: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

[ { "title": “We are in APIConference!”, "subtitle": “APIConference”, "user": “localhost:8080/o/p/30325” }, { "title": “5 amazing things!”, "subtitle": “Get english!”, "user": “localhost:8080/o/p/30325” }]

localhost:8080/o/api/blogs?start=25&end=27

[ { "headline": “We are in APIConference!”, "alternativeHeadline”: “APIConference”, "author": “localhost:8080/o/p/30325” }, { "headline": “5 amazing things!”, "alternativeHeadline": “Get english!”, "author": “localhost:8080/o/0/65443” }]

Page 60: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs
Page 61: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

{ “count”: 2, “totalItems”: 30, “members”: [ { "headline": “We are in APIConference!”, "alternativeHeadline": “APIConference”, "author": “localhost:8080/o/p/30325” }, { "headline": “5 amazing things!”, "alternativeHeadline": “Get english!”, "author": “localhost:8080/o/0/65443” } ], “view”: { “next”: “localhost:8080/blogs?p=7&p_p=2” }}

localhost:8080/o/api/blogs?page=6&per_page=2

[ { "title": “We are in APIConference!”, "subtitle": “THE conference for APIs”, "user": “localhost:8080/o/p/30325” }, { "title": “5 amazing things to do in London!”, "subtitle": “Get english!”, "user": “localhost:8080/o/0/65443” }]

Page 62: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

How do I add support for queries?

Page 63: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

OData’s

Page 64: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

all

Page 65: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs
Page 66: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs
Page 67: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Project: Platform APIsAPI stack: Java with OSGi and JAX-RSConsumers: Mobile Apps, Think Web clients, ESBs, Legacy Apps, ... 2

Page 68: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Home URL

{ "resources": { "blog-postings": { "href": "http://localhost:8080/p/blog-postings" }, "web-sites": { "href": "http://localhost:8080/p/web-sites" }, "documents": { "href": "http://localhost:8080/p/documents" },

"organizations": { "href": "http://localhost:8080/p/organizations" }, "people": { "href": "http://localhost:8080/p/people" } }}

JSON-HOME

Page 69: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs
Page 70: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Affordance Types

{ "@context": [ { "creator": { "@type": "@id" } }, { "@vocab": "http://schema.org/" }, "https://www.w3.org/ns/hydra/core#" ], "@id": "http://localhost:8080/p/blog-postings/0", "@type": "BlogPosting", "alternativeHeadline": "Et eaque quod.", "articleBody": "Sunt adipisci eligendi dolorem ducimus placeat.", "creator": "http://localhost:8080/p/people/9", "dateCreated": "2017-07-11T11:06Z", "dateModified": "2017-07-11T11:06Z", "headline": "Alone on a Wide, Wide Sea"}

JSON-LD + HYDRA

Page 71: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Affordance Types

{ "@id": "http://localhost:8080/p/blog-postings/0", "@type": "BlogPosting", "creator": "http://localhost:8080/p/people/9", "headline": "Alone on a Wide, Wide Sea", "operation": [ { "@id": "_:blog-postings/delete", "@type": "Operation", "method": "DELETE" }, { "@id": "_:blog-postings/update", "@type": "Operation", "expects": "http://localhost:8080/f/u/blog-postings", "method": "PUT" } ]}

JSON-LD + HYDRA

Page 72: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Affordance Types

{ "@id": "http://localhost:8080/f/u/blog-postings", "@type": "Class", "description": "This can be used to create or update a blog posting", "supportedProperty": [ { "@type": "SupportedProperty", "property": "creator", "required": false, }, { "@type": "SupportedProperty", "property": "headline", "required": true, } ], "title": "The blog posting form"}

JSON-LD + HYDRA

Page 73: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Representor pattern

Page 74: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Apio

Page 75: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

public Representor<BlogPostingModel, Long> representor( Builder<BlogPostingModel, Long> builder) {

return builder.types( "BlogPosting" ).identifier( BlogPostingModel::getId ).addDate( "dateModified", BlogPostingModel::getModifiedDate ).addLinkedModel( "creator", PersonId.class, BlogPostingModel::getCreatorId ).addRelatedCollection( "comment", BlogPostingCommentId.class ).addString( "alternativeHeadline", BlogPostingModel::getSubtitle ).addString( "articleBody", BlogPostingModel::getContent ).addString( "headline", BlogPostingModel::getTitle ).build();}

Well defined custom types

Page 76: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs
Page 78: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Project: Data Integration through ETL/ESBConsumer: Talend Plugin 3

Page 81: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Final Lessons!|

Page 82: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Your needs > Any specific solution

Page 83: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

REST Shared Vocabularies +

Page 84: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Spend time defining your vocabulary

Page 85: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

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

Page 86: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Giving Back

Page 87: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Apio: An Open Source Project

Apio Architect

●●

Apio Consumer

Page 88: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs
Page 89: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs
Page 90: The Liferay case - API Conference...Conclusions - The Good Enabled the possibility of integration with external systems Easy to build APIs thanks to code generation from Java APIs

Recommended