enhance existing rest apis (e.g. facebook graph api) with code completion using swagger/spring-...
Post on 21-Jan-2018
1.669 Views
Preview:
TRANSCRIPT
@johannes_fiala#Devoxx #Swagger
Enhance existing REST APIs
(e.g. Facebook Graph API) with
code completion using
Swagger/SpringJohannes Fiala
FWD
`
@johannes_fiala#Devoxx #Swagger
Enhance REST APIs
• Add API documentation (like WSDL schema)
• Describes the Service/request/response/models
• + add description for others to understand
• In a standardized way = according to Swagger Spec.
• Using a standardized structure, datatype names, references to
models, …
@johannes_fiala#Devoxx #Swagger
Enhance REST APIs
Benefits• Makes the payload predictable
• Allows to use tools using the Swagger-standard
• Use Swagger-UI for exploring the API
• Generate client code with Swagger-Codegen
• Get Code completion for 20+ programming languages
• Ship SDKs in target languages
• Get correct datatypes in client code
• Get Enum support
• Get Compile-time checking of consistency
@johannes_fiala#Devoxx #Swagger
How to enhance REST APIs?
• Ask API provider to provide Swagger apidocs
• If using Spring: Springfox-libraries
• If not: see Swagger-Spring integrations
• If not possible:
• Create Swagger apidocs on your own
• Demo Today: Facebook Graph API
• Other REST-API‘s you‘d like to have enhanced?
• Google Maps API?
• ???
@johannes_fiala#Devoxx #Swagger
In the next few minutes you‘ll learn
…• Introduction to Springfox/Swagger-Codegen
• Basic overview of Facebook Graph API
• Step-by-step Demo of using Swagger-Codegen to extract
Metadata & add them to the model
• Extract standard apidocs for Facebook
• Learn about using Swagger-Codegen
• Support of Bean Validation API: add
@NotNull/@Min/@Max by adding your own
BuilderPlugins
@johannes_fiala#Devoxx #Swagger
Technology stack
• Spring
• Spring Boot for fast start
• also possible: Spring REST/MVC
• Springfox
• For generating the api-docs
• Swagger UI
• For accessing the api using a browser
• Swagger Codegen commandline
• For generating client code stubs
@johannes_fiala#Devoxx #Swagger
Big Picture
Your REST-API
Springfox/v2/api-docs/
Swagger-UI/swagger/index.html
Swagger-
Codegen
Client-CodeJava, PHP, C#, Ruby, nodejs,
Objective-C, …
@johannes_fiala#Devoxx #Swagger
Springfox
• Provide complete api-docs for every @RESTController
• Services
• Supported Verbs (GET/POST/…)
• Request parameters/body
• Response codes + body
• Many customization options (hide attributes, custom data
types, …)
@johannes_fiala#Devoxx #Swagger
Swagger Codegen
• Client code stub generator (commandline)
• Generates completely customizable client stubs
• Supported languages:
• Java, C#, Dart, Flash, Groovy, JaxRS, NodeJS,
Objective-C, Perl, PHP, Python, Ruby, Scala, ….
• Ensures consistency of your client code with the API!
@johannes_fiala#Devoxx #Swagger
Swagger Codegen
• io.swagger.codegen.DefaultGenerator.generate():
• Reads api-docs in json syntax
• Scans each model
• Scans all the model properties
• Then compiles language-specific Mustache templates using a
language-specific Configuration class
• Language specific configuration:
• io.swagger.codegen.languages.*
• Mustache files: src/main/resources
@johannes_fiala#Devoxx #Swagger
Big Picture
Facebook Graph
API
Springfox/v2/api-docs/
Swagger-
Codegen
Client-Code
Facebook Proxy
REST Service
generates (2)
calls (3)
Read field metadata (1)
@johannes_fiala#Devoxx #Swagger
Facebook Graph API
• Basic docs:
https://developers.facebook.com/docs/graph-
api/overview
• Graph API Explorer:
https://developers.facebook.com/tools/explorer
• Nice for basic testing
• Retrieve your access token
@johannes_fiala#Devoxx #Swagger
Extract metadata from the Facebook
Graph API• Facebook Graph API url:
https://graph.facebook.com/v2.5/microsoft?access_token
=... &fields=name,about,mission
• Get field metadata: add parameter „&metadata=1“
@johannes_fiala#Devoxx #Swagger
Demo
• Demo of Facebook Graph API
@johannes_fiala#Devoxx #Swagger
Extract metadata from the Facebook
Graph API• Target: Provide Swagger apidocs for Facebook API
• Read metadata
• Add description to fields
• Map field types to standard datatypes
• Add Enumerations
• Swagger Codegen has the Model data available during
processing and can be extended
• Alternative: Json transformation from metadata to
Swagger api
@johannes_fiala#Devoxx #Swagger
Preparation work
• a Facebook-Account
• Checkout/Download the demo project
https://github.com/jfiala/swagger-springfox-demo
@johannes_fiala#Devoxx #Swagger
Preparation work
• Modules of the swagger-springfox-demo:
• Swagger-codegen-2.1.3-facebook
• The customized Swagger-codegen code for Facbeook
• User-rest-service-2.2.2-facebook
• The Spring Boot REST-API application
• User-rest-service-2.2.2-facebook-client-java-codegen
• The generated client stubs
@johannes_fiala#Devoxx #Swagger
Big Picture
Facebook Graph
API
Springfox/v2/api-docs/
Swagger-
Codegen
Client-Code
Facebook Proxy
REST Service
generates (2)
calls (3)
Read metadata (1)
@johannes_fiala#Devoxx #Swagger
Define the server proxy
• ConnectorUserFacebookController:
• Uses basic FacebookUser-model (with 2 attributes)
• No need to recode representation class
• Connects to Facebook using Spring Rest
• Try it using Swagger-UI
@johannes_fiala#Devoxx #Swagger
Demo
• Demo of Facebook server proxy
@johannes_fiala#Devoxx #Swagger
Big Picture
Facebook Graph
API
Springfox/v2/api-docs/
Swagger-
Codegen
Client-Code
Facebook Proxy
REST Service
generates (2)
calls (3)
Read metadata (1)
@johannes_fiala#Devoxx #Swagger
Add metadata fields to Swagger-
Codegen• Add fields listed in metadata
• Add field description
• Map FB field type to Swagger standard datatype
• Extract Enumerations out of description
• Add JSR-303 @NotNull, (@Min, @Max)
• + ???
• Add further Bean Validation Annotations (e.g. Size)?
• Further suggestions?
@johannes_fiala#Devoxx #Swagger
Add metadata fields to Swagger-
Codegen• Important class: DefaultGenerator
• Line: Model model = definitions.get(name);String access_token =„…";
String url = "https://graph.facebook.com/pivotalsoftware?access_token=" + access_token + "&metadata=1";
FacebookUser user = readJsonFromUrl(url);
for (FacebookField field : user.getMetadata().getFields()) {
propName = field.getName();
// add new virtual fields from Facebook to the model
virtualProperty = new StringProperty();
virtualProperty.setName(propName);
virtualProperty.setDescription(field.getDescription());
model.getProperties().put(propName, virtualProperty);
}
@johannes_fiala#Devoxx #Swagger
Add metadata fields to Swagger-
Codegen• Map Facebook datatypes to Swagger datatypes
// Examples of data type mappings from Facebook-Datatypes to Swagger-Model-Datatypes
if ("bool".equals(field.getType())) {
virtualProperty = new BooleanProperty();
} else if ("unsigned int32".equals(field.getType())){
virtualProperty = new IntegerProperty();
} else {
virtualProperty = new StringProperty();
}
@johannes_fiala#Devoxx #Swagger
Add metadata fields to Swagger-
Codegen• Extract Enum datatypes (e.g. attire)• Description: "Dress code of the business. Applicable to Restaurants or Nightlife.
Can be one of Casual, Dressy or Unspecified“
StringProperty myStringProperty = (StringProperty)virtualProperty;
String myEnumValues = StringUtils.substringAfter(field.getDescription(), "Can be one of");
myEnumValues = StringUtils.replace(myEnumValues, " or ", ", ");
String[] enumValues = StringUtils.split(myEnumValues);
for (String myEnum : enumValues) {
myStringProperty._enum(myEnum );
}
@johannes_fiala#Devoxx #Swagger
Running the code generator
• io.swagger.codegen.Codegen -i
http://localhost:8080/v2/api-docs/ -l java –o ../facebook-
client-java
@johannes_fiala#Devoxx #Swagger
View the generated code
• The FacebookUser now has all fields of the Graph API!@ApiModel(description = "")
public class FacebookUser {
/**
* Information about the Page
**/
@ApiModelProperty(value = "Information about the Page")
@JsonProperty("about")
public String getAbout() {
return about;
}
…
@johannes_fiala#Devoxx #Swagger
Demo
• Demo of Swagger-Codegen
@johannes_fiala#Devoxx #Swagger
Big Picture
Facebook Graph
API
Springfox/v2/api-docs/
Swagger-
Codegen
Client-Code
Facebook Proxy
REST Service
generates (2)
calls (3)
Read metadata (1)
@johannes_fiala#Devoxx #Swagger
Client code:
Access Facebook directly
• Junit-Test: Facebook_Test.java
• Change basepath:// TODO Step 1: replace basepath
api.getApiClient().setBasePath("https://graph.faceboo
k.com/v2.5/");
@johannes_fiala#Devoxx #Swagger
Adding a custom language
• See JavaFacebookClientCodegen
• Defines template-directory is JavaFacebook
• Now we can modify the Model
• Add @NotNull
• Add @Min, @Max
@johannes_fiala#Devoxx #Swagger
Running the code generator
• io.swagger.codegen.Codegen -i
http://localhost:8080/v2/api-docs/ -l java –o ../facebook-
client-java
@johannes_fiala#Devoxx #Swagger
Get Swagger apidocs
• Get Swagger apidocs
• Access FB through Proxy using Swagger-UI
• See model definitions in the browser
• Replace the model class „FacebookUser“
• Restart Spring Boot
• Inspect the updated model using the Swagger-UI
http://localhost:8080/swagger/index.html
@johannes_fiala#Devoxx #Swagger
Demo
• Demo of Facebook server proxy
with new FacebookUser-class
@johannes_fiala#Devoxx #Swagger
Wrapup
• Learned:
• You are able to add fields dynamically to a model class during
client-code-generation, add datatype-mapping and enums
• You are able to access the Facebook Graph API directly
• You are able to add custom languages
• Benefits:
• You can generate client code for every language supported by
Swagger-Codegen
• You have code completion for all model attributes!
@johannes_fiala#Devoxx #Swagger
Possible improvements
• Structures (e.g. Location) are currently not part of the
Facebook metadata and need to be created manually as
representation classes
• Some fields are only accessible with specific
permissions, but that‘s also not visible in the metadata
• See Helper-class AssembleFieldsUtil for details
• JSR-303 support needs further improvement
• @Min/@Max, @Size, …
@johannes_fiala#Devoxx #Swagger
Support for Beans Validation API
(JSR 303)• Not yet implemented
• See Issue for discussion:
https://github.com/springfox/springfox/issues/356
• Can be done using extensions (Plugin Builders)
@johannes_fiala#Devoxx #Swagger
Support for Beans Validation API
How to add it yourself:• Using „Plugins“ you can override/add to the behaviour of
Builders for Parameters/the Model
• Add a component implementing the Plugin-Interface,
e.g. ModelPropertyBuilderPlugin
• You get access to the processing context
• You can query for annotations there
• Examples: @NotNull, @Min/@Max
@johannes_fiala#Devoxx #Swagger
Support for Beans Validation API
Further available plugins• Available Plugins for Model/Parameters:
• ModelBuilderPlugin
• ModelPropertyBuilderPlugin
• ParameterBuilderPlugin
@johannes_fiala#Devoxx #Swagger
Fine-Tuning Spring Boot
• Spring Boot adds /error path automatically
• Get rid of it using
new Docket(…)…
.apis(Predicates.not(RequestHandlerSelectors.basePack
age("org.springframework.boot")))
@johannes_fiala#Devoxx #Swagger
Hot Deploy using Spring Loaded
• Allows hot deploy
• for adding new methods etc.
• Add JVM parameters:
• -javaagent:/path_to_spring-loaded/springloaded-
1.2.4.RELEASE.jar -noverify
• https://github.com/spring-projects/spring-loaded
• http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-hotswapping
@johannes_fiala#Devoxx #Swagger
Links & Resources
• Swagger.io
http://swagger.io/open-source-integrations/
• Springfox
http://springfox.github.io/springfox/
@johannes_fiala#Devoxx #Swagger
Links & Resources
• Swagger UI
https://github.com/swagger-api/swagger-ui
• Swagger Codegen
https://github.com/swagger-api/swagger-codegen
• Chrome Plugin Swagger.ed
https://github.com/chefArchitect/apispots-browser-
swaggered
@johannes_fiala#Devoxx #Swagger
Thank you for your attention!
• Contact:
• johannes.fiala@fwd.at
top related