SlideShare una empresa de Scribd logo
1 de 82
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Embracing Change Without
Breaking The World
J i m F l a n a g a n – S o f t w a r e E n g i n e e r – A W S C r y p t o g r a p h y
K y l e T h o m s o n – S o f t w a r e E n g i n e e r – A W S S D K
D E V 3 1 9
N o v e m b e r 3 0 , 2 0 1 7
AWS re:INVENT
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Introduction
• AWS has 90+ services and deploys API updates several times a week (often daily)
• Backwards compatibility is necessary
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Who are we?
• API review bar-raisers
• Experienced API reviewers and library designers
• Responsible for quality of AWS APIs
• Ensure backwards compatibility of API changes
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Agenda
• Definitions
• What’s backwards compatibility and why is it important?
• What’s an API (by way of example)?
• Changing an API
• What’s safe to do in the API?
• How should we design our clients?
• API constraints and validation
• Client-side concerns
• Exceptions
• Undocumented API contracts
• Sharing shapes
• Backwards compatibility rules
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Definitions
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
How APIs evolve relative to clients
API
Client
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
How APIs evolve relative to clients
API
Client
API
v2
Client
v2
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
How APIs evolve relative to clients
API
Client
API
v2
Client
v2
API
v3
Client
v3
API
v4
Client
v4
API
vN
Client
vN
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
How APIs evolve relative to clients
API
Client
API´
Client´
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
How APIs evolve relative to clients
Client
API´
Client´
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Anatomy of a Web API—resources
Trip
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Anatomy of a Web API—resources
Trip
travelers: [string]
description: string
…
“Shape"
“Member”
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Anatomy of a Web API—resources
Trip
travelers: [string]
description: string
flight: Flight
Flight
airline: string
status: string
…
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Anatomy of a Web API
PutTrip
GetTrip
ListTrips
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Anatomy of a Web API
PUT /Trips
GET /Trips/{id}
GET /Trips
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Anatomy of a Web API
123
GetTrip
{ “travelers”: [“Jim”],
“description”: “re:Invent” }
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Anatomy of a Web API
123
GetTrip
{ “travelers”: [“Jim”],
“description”: “re:Invent” }
Input
shape
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Anatomy of a Web API
123
GetTrip
{ “travelers”: [“Jim”],
“description”: “re:Invent” }
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Anatomy of a Web API
321
GetTrip
ResourceNotFound
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Summary of definitions
• Resources—things that an API manages
• Shape—some structure with members
• Input shape—a top-level request shape passed to an operation
• Output shape—a top-level response shape return from an operation
• Error shape—a structure that represents an error response from an operation
• Member—belongs to a shape represents some property
• Operation—something the service exposes that can be invoked (e.g. getTrips)
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Changing an API
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding/removing
Trip
travelers: [string]
description: string
origin: string
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding/removing
Trip
travelers: [string]
description: string
origin: string
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding/removing
Trip
travelers: [string]
description: string
origin: string
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding/removing
Trip
travelers: [string]
description: string
origin: string
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding/removing
Trip
travelers: [string]
description: string
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding members
public final class Trip {
private final List<String> travelers;
private final String description;
public Trip(List<String> travelers, String description) {
this.travelers = travelers;
this.description = description;
}
public List<String> getTravelers() {
return travelers;
}
public String getDescription() {
return description;
}
}
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding members
List<String> travelers = Collections.singletonList("Jim");
Trip myTrip = new Trip(travelers, "re:Invent");
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding/removing
Trip
travelers: [string]
description: string
origin: string
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding members to the constructor
public Trip(List<String> travelers, String description, String origin) {
this.travelers = travelers;
this.description = description;
this.origin = origin;
}
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding members to the constructor
public Trip(List<String> travelers, String description, String origin) {
this.travelers = travelers;
this.description = description;
this.origin = origin;
}
Trip myTrip = new Trip(travelers, "re:Invent");
Won’t
compile
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Constructor overload
public Trip(List<String> travelers, String description) {
this(travelers, description, null);
}
public Trip(List<String> travelers, String description, String origin) {
this.travelers = travelers;
this.description = description;
this.origin = origin;
}
Trip myTrip = new Trip(travelers, "re:Invent");
Trip myTrip = new Trip(travelers, "re:Invent”, “USA”);
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
All constructor combinations
public Trip(List<String> travelers, String description, String origin)
public Trip(List<String> travelers, String description)
public Trip(List<String> travelers)
public Trip(String description, String origin)
public Trip(String description)
public Trip(List<String> travelers, String origin)
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
All constructor combinations
public Trip(List<String> travelers, String description, String origin)
public Trip(List<String> travelers, String description)
public Trip(List<String> travelers)
public Trip(String description, String origin)
public Trip(String description)
public Trip(List<String> travelers, String origin)
public Trip(String origin)
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
All constructor combinations
public Trip(List<String> travelers, String description, String origin)
public Trip(List<String> travelers, String description)
public Trip(List<String> travelers)
public Trip(String description, String origin)
public Trip(String description)
public Trip(List<String> travelers, String origin)
public Trip(String origin)
Clash!
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Languages with default values
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding members
public final class Trip {
private List<String> travelers;
private String description;
public Trip() { }
public void setTravelers(List<String> travelers) { this.travelers = travelers; }
public void setDescription(String description) { this.description = description; }
/** getters omitted **/
}
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding members
public final class Trip {
private List<String> travelers;
private String description;
public Trip() { }
public void setTravelers(List<String> travelers) { this.travelers = travelers; }
public void setDescription(String description) { this.description = description; }
/** getters omitted **/
}
Trip trip = new Trip();
trip.setTravelers(travelers);
trip.setDescription("re:Invent");
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding members
public final class Trip {
private List<String> travelers;
private String description;
private String origin;
public Trip() { }
public void setTravelers(List<String> travelers) { this.travelers = travelers; }
public void setDescription(String description) { this.description = description; }
public void setOrigin(String origin) { this.origin = origin; }
}
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding members
public final class Trip {
private List<String> travelers;
private String description;
private String origin;
public Trip() { }
public void setTravelers(List<String> travelers) { this.travelers = travelers; }
public void setDescription(String description) { this.description = description; }
public void setOrigin(String origin) { this.origin = origin; }
}
Models
are
mutable
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding members
public final class Trip {
private final List<String> travelers;
private final String description;
private Trip(Builder builder) {
this.travelers = builder.travelers;
this.description = builder.description;
}
public static Builder builder() { return new Builder(); }
public static class Builder {
private List<String> travelers;
private String description;
public Builder travelers(List<String> travelers) { this.travelers = travelers; return this; }
public Builder description(String description) { this.description = description; return this; }
public Trip build() { return new Trip(this); }
}
}
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding members
public final class Trip {
private final List<String> travelers;
private final String description;
private Trip(Builder builder) {
this.travelers = builder.travelers;
this.description = builder.description;
}
public static Builder builder() { return new Builder(); }
public static class Builder {
private List<String> travelers;
private String description;
public Builder travelers(List<String> travelers) { this.travelers = travelers; return this; }
public Builder description(String description) { this.description = description; return this; }
public Trip build() { return new Trip(this); }
}
}
Members
are final
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding members
public final class Trip {
private final List<String> travelers;
private final String description;
private Trip(Builder builder) {
this.travelers = builder.travelers;
this.description = builder.description;
}
public static Builder builder() { return new Builder(); }
public static class Builder {
private List<String> travelers;
private String description;
public Builder travelers(List<String> travelers) { this.travelers = travelers; return this; }
public Builder description(String description) { this.description = description; return this; }
public Trip build() { return new Trip(this); }
}
}
Constructor
is private
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding members
public final class Trip {
private final List<String> travelers;
private final String description;
private Trip(Builder builder) {
this.travelers = builder.travelers;
this.description = builder.description;
}
public static Builder builder() { return new Builder(); }
public static class Builder {
private List<String> travelers;
private String description;
public Builder travelers(List<String> travelers) { this.travelers = travelers; return this; }
public Builder description(String description) { this.description = description; return this; }
public Trip build() { return new Trip(this); }
}
}
Trip trip = Trip.builder()
.travelers(travelers)
.description("re:Invent")
.build();
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding members
public final class Trip {
private final List<String> travelers;
private final String description, origin;
private Trip(Builder builder) {
this.travelers = builder.travelers;
this.description = builder.description;
this.origin = builder.origin;
}
public static Builder builder() { return new Builder(); }
public static class Builder {
private List<String> travelers;
private String description, origin;
public Builder travelers(List<String> travelers) { this.travelers = travelers; return this; }
public Builder description(String description) { this.description = description; return this; }
public Builder origin(String origin) { this.origin = origin; return this; }
public Trip build() { return new Trip(this); }
}
}
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Constraints & Validation
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding—caveats
Trip
travelers: [string]
description: string
origin: string
destination: stringRequired
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding—caveats
Flight
airline: string
status: FlightStatusEnum
…
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding—caveats
Requested
RejectedBooked Terminal
state
Processing
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding—caveats
Requested
Processing
RejectedBooked Error
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Adding—caveats
Requested
Processing
…
Review
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Enumerations in code
public final class Flight {
private final String airline;
private final FlightStatus status;
private Flight(String airline, FlightStatus status) {
this.airline = airline;
this.status = status;
}
public String getAirline() { return airline; }
public FlightStatus getStatus() { return status; }
}
public enum FlightStatus {
REQUESTED, PROCESSING, BOOKED, REJECTED;
}
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Enumerations in code
public final class Flight {
private final String airline;
private final String status;
private Flight(String airline, String status) {
this.airline = airline;
this.status = status;
}
public String getAirline() { return airline; }
public String getStatus() { return status; }
}
FlightStatus.valueOf(flight.getStatus());
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Enumerations in code
public enum FlightStatus {
REQUESTED, PROCESSING, BOOKED, REJECTED, SDK_UNKNOWN;
}
public final class Flight {
private final String airline;
private final String status;
public FlightStatus getStatus() {
try {
return FlightStatus.valueOf(status);
} catch (IllegalArgumentException e) {
return FlightStatus.SDK_UNKNOWN;
}
}
}
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Enumerations in code
public enum FlightStatus {
REQUESTED, PROCESSING, BOOKED, REJECTED, SDK_UNKNOWN;
}
public final class Flight {
private final String airline;
private final String status;
public FlightStatus getStatus() {
try {
return FlightStatus.valueOf(status);
} catch (IllegalArgumentException e) {
return FlightStatus.SDK_UNKNOWN;
}
}
public String getStatusAsString() { return status; }
}
switch(flight.getStatus()) {
case BOOKED: System.out.println("Yay!");
case SDK_UNKNOWN:
System.out.println("Unknown value: " +
flight.getStatusAsString());
}
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Client side validation
public final class Trip {
private final List<String> travelers;
private final String description;
private Trip(Builder builder) {
this.travelers = Validate.hasSize(builder.travelers, 1);
this.description = Validate.notNull(builder.description);
}
@NotNull
public List<String> travelers() { return travelers; }
@NotNull
public String description() { return description; }
}
fun descriptionLength(): Int = trip.description().length
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Client side validation
public final class Trip {
private final List<String> travelers;
private final String description;
private Trip(Builder builder) {
this.travelers = Validate.hasSize(builder.travelers, 1);
this.description = builder.description;
}
@NotNull
public List<String> travelers() { return travelers; }
@NotNull
public String description() { return description; }
}
fun descriptionLength(): Int = trip.description()?.length
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Source Compatibility
public interface TripClient {
void putTrip(PutTripRequest request);
GetTripResponse getTrip(GetTripRequest request);
GetTripsResponse getTrips();
}
TripClient tripClient = ...;
tripClient.putTrip(putTripRequest);
response = tripClient.getTrip(getTripRequest);
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Source Compatibility
public interface TripClient {
PutTripResponse putTrip(PutTripRequest request);
GetTripResponse getTrip(GetTripRequest request);
GetTripsResponse getTrips();
}
TripClient tripClient = ...;
tripClient.putTrip(putTripRequest);
response = tripClient.getTrip(getTripRequest);
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Binary Compatibility
public interface TripClient {
void putTrip(PutTripRequest trip);
}
public interface TripClient {
PutTripResponse putTrip(PutTripRequest trip);
}
TripClient tripClient = ...;
tripClient.putTrip(putTripRequest);
response = tripClient.getTrip(getTripRequest);
NoSuchMethod
Exception
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Exceptions
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Exceptions
PutFlight:
Input:
PutFlightRequest
Output:
Flight | ValidationError
| UnknownAirportError
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Exceptions
PutFlightRequest
airline: string
date: dateTime
ValidationError
InvalidDateError
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Exceptions
ValidationError
message: string
field: string
validationType: VTypeEnum
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Undocumented API Contracts
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Undocumented API contracts
Hyrum’s Law–With sufficient number
of users of an API, it does not matter
what you promise in the contract, all
observable behaviors of your system
will be depended on by somebody
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
”ListTripsRequest” : {
”nextToken”
…
}
”ListTripsResult” : {
”nextToken”
…
}
Undocumented API contracts
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
”ListTripsRequest” : {}
”ListTripsRequest” : {
”nextToken” : “page2”
}
”ListTripsResult” : {
“items” : [ … ],
”nextToken” : ”page2” }
Undocumented API contracts
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Undocumented API contracts
”ListTripsRequest” : {
”nextToken” : “page2000”
}
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
”ListTripsRequest” : {}
”ListTripsRequest” : {
”nextToken” : “page2”
}
”ListTripsResult” : {
“items” : [ … ],
”nextToken” : ”10-20” }
Undocumented API contracts
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
”ListTripsRequest” : {}
”ListTripsRequest” : {
”nextToken” : “page2”
}
”ListTripsResult” : {
“items” : [ … ],
”nextToken” : ”10-20” }
Undocumented API contracts
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Undocumented API contracts
”ListTripsResponse” : {
“items”: [ … ],
”nextToken” : “cGFnZTIK”
}
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Sharing Shapes
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Sharing shapes
UpdateFlight:
Input: Flight
Output: Flight
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Sharing shapes
Flight
airline: string
status: FlightStatusEnum
lastModified: Date
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Sharing shapes
UpdateFlight:
Input: Flight
Output: Flight
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Sharing shapes
UpdateFlight:
Input: UpdateFlightRequest
Output: Flight
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Backwards Compatibility Rules
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
The Good (Dos)
API
• Adding members/shapes
• Adding intermediate (non-terminal) workflow
states
• Adding details to exceptions (error codes)
• Adding new opt-in exceptions
• Loosening constraints (e.g. increase max length)
Client
• Forward compatible (support all of the above)
• Focus on discoverability
The Bad (Don’ts)
API
• Removing/renaming members/shapes
• Changing the type of members
• Adding new terminal workflow states
• Adding exceptions without opt-in
• Tightening constraints (e.g. decrease max-length)
Client
• Validating API constraints
The Rules
© 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
Thank you!
D E V 3 1 9

Más contenido relacionado

Similar a Embracing Change without Breaking the World - DEV319 - re:Invent 2017

Deep-Dive for AWS X-Ray - DEV402 - re:Invent 2017
Deep-Dive for AWS X-Ray - DEV402 - re:Invent 2017Deep-Dive for AWS X-Ray - DEV402 - re:Invent 2017
Deep-Dive for AWS X-Ray - DEV402 - re:Invent 2017Amazon Web Services
 
Metering the Hybrid Cloud - ARC404 - re:Invent 2017
Metering the Hybrid Cloud - ARC404 - re:Invent 2017Metering the Hybrid Cloud - ARC404 - re:Invent 2017
Metering the Hybrid Cloud - ARC404 - re:Invent 2017Amazon Web Services
 
Use Amazon Rekognition to Build a Facial Recognition System
Use Amazon Rekognition to Build a Facial Recognition SystemUse Amazon Rekognition to Build a Facial Recognition System
Use Amazon Rekognition to Build a Facial Recognition SystemAmazon Web Services
 
Use Amazon Rekognition to Build a Facial Recognition System
Use Amazon Rekognition to Build a Facial Recognition SystemUse Amazon Rekognition to Build a Facial Recognition System
Use Amazon Rekognition to Build a Facial Recognition SystemAmazon Web Services
 
Real Time and Offline Applications with GraphQL
Real Time and Offline Applications with GraphQLReal Time and Offline Applications with GraphQL
Real Time and Offline Applications with GraphQLAmazon Web Services
 
RET305-Turbo Charge Your E-Commerce Site wAmazon Cache and Search Solutions.pdf
RET305-Turbo Charge Your E-Commerce Site wAmazon Cache and Search Solutions.pdfRET305-Turbo Charge Your E-Commerce Site wAmazon Cache and Search Solutions.pdf
RET305-Turbo Charge Your E-Commerce Site wAmazon Cache and Search Solutions.pdfAmazon Web Services
 
Avoiding Groundhog Day - Enabling Transformation on Day 1, 100, or 1000 of yo...
Avoiding Groundhog Day - Enabling Transformation on Day 1, 100, or 1000 of yo...Avoiding Groundhog Day - Enabling Transformation on Day 1, 100, or 1000 of yo...
Avoiding Groundhog Day - Enabling Transformation on Day 1, 100, or 1000 of yo...Amazon Web Services
 
Develop Cross-Platform Mobile Apps with React Native, GraphQL, & AWS (MOB324)...
Develop Cross-Platform Mobile Apps with React Native, GraphQL, & AWS (MOB324)...Develop Cross-Platform Mobile Apps with React Native, GraphQL, & AWS (MOB324)...
Develop Cross-Platform Mobile Apps with React Native, GraphQL, & AWS (MOB324)...Amazon Web Services
 
NEW LAUNCH! AWS IoT Device Management - IOT330 - re:Invent 2017
NEW LAUNCH! AWS IoT Device Management - IOT330 - re:Invent 2017NEW LAUNCH! AWS IoT Device Management - IOT330 - re:Invent 2017
NEW LAUNCH! AWS IoT Device Management - IOT330 - re:Invent 2017Amazon Web Services
 
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdfMonetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdfAmazon Web Services
 
DEV203_Launch Applications the Amazon Way
DEV203_Launch Applications the Amazon WayDEV203_Launch Applications the Amazon Way
DEV203_Launch Applications the Amazon WayAmazon Web Services
 
Building & Deploying Your First Serverless Application
Building & Deploying Your First Serverless ApplicationBuilding & Deploying Your First Serverless Application
Building & Deploying Your First Serverless ApplicationAmazon Web Services
 
DEV209 A Field Guide to Monitoring in the Cloud: From Lift and Shift to AWS L...
DEV209 A Field Guide to Monitoring in the Cloud: From Lift and Shift to AWS L...DEV209 A Field Guide to Monitoring in the Cloud: From Lift and Shift to AWS L...
DEV209 A Field Guide to Monitoring in the Cloud: From Lift and Shift to AWS L...New Relic
 
DEV204_Debugging Modern Applications Introduction to AWS X-Ray
DEV204_Debugging Modern Applications Introduction to AWS X-RayDEV204_Debugging Modern Applications Introduction to AWS X-Ray
DEV204_Debugging Modern Applications Introduction to AWS X-RayAmazon Web Services
 
Running Container on AWS - Builders Day Israel
Running Container on AWS - Builders Day IsraelRunning Container on AWS - Builders Day Israel
Running Container on AWS - Builders Day IsraelAmazon Web Services
 
Simpler by Design: Build a Better GraphQL API for Your Next App by Writing Le...
Simpler by Design: Build a Better GraphQL API for Your Next App by Writing Le...Simpler by Design: Build a Better GraphQL API for Your Next App by Writing Le...
Simpler by Design: Build a Better GraphQL API for Your Next App by Writing Le...Amazon Web Services
 
NEW LAUNCH! Introducing Amazon EKS - CON215 - re:Invent 2017
NEW LAUNCH! Introducing Amazon EKS - CON215 - re:Invent 2017NEW LAUNCH! Introducing Amazon EKS - CON215 - re:Invent 2017
NEW LAUNCH! Introducing Amazon EKS - CON215 - re:Invent 2017Amazon Web Services
 
Journey Towards Scaling Your API to 10 Million Users
Journey Towards Scaling Your API to 10 Million UsersJourney Towards Scaling Your API to 10 Million Users
Journey Towards Scaling Your API to 10 Million UsersAdrian Hornsby
 
Alexa連携デバイスクラウドを構成するAWS ソリューション
Alexa連携デバイスクラウドを構成するAWS ソリューションAlexa連携デバイスクラウドを構成するAWS ソリューション
Alexa連携デバイスクラウドを構成するAWS ソリューションToshiaki Enami
 

Similar a Embracing Change without Breaking the World - DEV319 - re:Invent 2017 (20)

Deep-Dive for AWS X-Ray - DEV402 - re:Invent 2017
Deep-Dive for AWS X-Ray - DEV402 - re:Invent 2017Deep-Dive for AWS X-Ray - DEV402 - re:Invent 2017
Deep-Dive for AWS X-Ray - DEV402 - re:Invent 2017
 
Metering the Hybrid Cloud - ARC404 - re:Invent 2017
Metering the Hybrid Cloud - ARC404 - re:Invent 2017Metering the Hybrid Cloud - ARC404 - re:Invent 2017
Metering the Hybrid Cloud - ARC404 - re:Invent 2017
 
Use Amazon Rekognition to Build a Facial Recognition System
Use Amazon Rekognition to Build a Facial Recognition SystemUse Amazon Rekognition to Build a Facial Recognition System
Use Amazon Rekognition to Build a Facial Recognition System
 
Use Amazon Rekognition to Build a Facial Recognition System
Use Amazon Rekognition to Build a Facial Recognition SystemUse Amazon Rekognition to Build a Facial Recognition System
Use Amazon Rekognition to Build a Facial Recognition System
 
Real Time and Offline Applications with GraphQL
Real Time and Offline Applications with GraphQLReal Time and Offline Applications with GraphQL
Real Time and Offline Applications with GraphQL
 
RET305-Turbo Charge Your E-Commerce Site wAmazon Cache and Search Solutions.pdf
RET305-Turbo Charge Your E-Commerce Site wAmazon Cache and Search Solutions.pdfRET305-Turbo Charge Your E-Commerce Site wAmazon Cache and Search Solutions.pdf
RET305-Turbo Charge Your E-Commerce Site wAmazon Cache and Search Solutions.pdf
 
Avoiding Groundhog Day - Enabling Transformation on Day 1, 100, or 1000 of yo...
Avoiding Groundhog Day - Enabling Transformation on Day 1, 100, or 1000 of yo...Avoiding Groundhog Day - Enabling Transformation on Day 1, 100, or 1000 of yo...
Avoiding Groundhog Day - Enabling Transformation on Day 1, 100, or 1000 of yo...
 
Develop Cross-Platform Mobile Apps with React Native, GraphQL, & AWS (MOB324)...
Develop Cross-Platform Mobile Apps with React Native, GraphQL, & AWS (MOB324)...Develop Cross-Platform Mobile Apps with React Native, GraphQL, & AWS (MOB324)...
Develop Cross-Platform Mobile Apps with React Native, GraphQL, & AWS (MOB324)...
 
NEW LAUNCH! AWS IoT Device Management - IOT330 - re:Invent 2017
NEW LAUNCH! AWS IoT Device Management - IOT330 - re:Invent 2017NEW LAUNCH! AWS IoT Device Management - IOT330 - re:Invent 2017
NEW LAUNCH! AWS IoT Device Management - IOT330 - re:Invent 2017
 
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdfMonetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
Monetize Your Mobile App with Amazon Mobile Ads (MOB311) - AWS reInvent 2018.pdf
 
DEV203_Launch Applications the Amazon Way
DEV203_Launch Applications the Amazon WayDEV203_Launch Applications the Amazon Way
DEV203_Launch Applications the Amazon Way
 
Building & Deploying Your First Serverless Application
Building & Deploying Your First Serverless ApplicationBuilding & Deploying Your First Serverless Application
Building & Deploying Your First Serverless Application
 
DEV209 A Field Guide to Monitoring in the Cloud: From Lift and Shift to AWS L...
DEV209 A Field Guide to Monitoring in the Cloud: From Lift and Shift to AWS L...DEV209 A Field Guide to Monitoring in the Cloud: From Lift and Shift to AWS L...
DEV209 A Field Guide to Monitoring in the Cloud: From Lift and Shift to AWS L...
 
Introducing Amazon Fargate
Introducing Amazon FargateIntroducing Amazon Fargate
Introducing Amazon Fargate
 
DEV204_Debugging Modern Applications Introduction to AWS X-Ray
DEV204_Debugging Modern Applications Introduction to AWS X-RayDEV204_Debugging Modern Applications Introduction to AWS X-Ray
DEV204_Debugging Modern Applications Introduction to AWS X-Ray
 
Running Container on AWS - Builders Day Israel
Running Container on AWS - Builders Day IsraelRunning Container on AWS - Builders Day Israel
Running Container on AWS - Builders Day Israel
 
Simpler by Design: Build a Better GraphQL API for Your Next App by Writing Le...
Simpler by Design: Build a Better GraphQL API for Your Next App by Writing Le...Simpler by Design: Build a Better GraphQL API for Your Next App by Writing Le...
Simpler by Design: Build a Better GraphQL API for Your Next App by Writing Le...
 
NEW LAUNCH! Introducing Amazon EKS - CON215 - re:Invent 2017
NEW LAUNCH! Introducing Amazon EKS - CON215 - re:Invent 2017NEW LAUNCH! Introducing Amazon EKS - CON215 - re:Invent 2017
NEW LAUNCH! Introducing Amazon EKS - CON215 - re:Invent 2017
 
Journey Towards Scaling Your API to 10 Million Users
Journey Towards Scaling Your API to 10 Million UsersJourney Towards Scaling Your API to 10 Million Users
Journey Towards Scaling Your API to 10 Million Users
 
Alexa連携デバイスクラウドを構成するAWS ソリューション
Alexa連携デバイスクラウドを構成するAWS ソリューションAlexa連携デバイスクラウドを構成するAWS ソリューション
Alexa連携デバイスクラウドを構成するAWS ソリューション
 

Más de Amazon Web Services

Come costruire servizi di Forecasting sfruttando algoritmi di ML e deep learn...
Come costruire servizi di Forecasting sfruttando algoritmi di ML e deep learn...Come costruire servizi di Forecasting sfruttando algoritmi di ML e deep learn...
Come costruire servizi di Forecasting sfruttando algoritmi di ML e deep learn...Amazon Web Services
 
Big Data per le Startup: come creare applicazioni Big Data in modalità Server...
Big Data per le Startup: come creare applicazioni Big Data in modalità Server...Big Data per le Startup: come creare applicazioni Big Data in modalità Server...
Big Data per le Startup: come creare applicazioni Big Data in modalità Server...Amazon Web Services
 
Esegui pod serverless con Amazon EKS e AWS Fargate
Esegui pod serverless con Amazon EKS e AWS FargateEsegui pod serverless con Amazon EKS e AWS Fargate
Esegui pod serverless con Amazon EKS e AWS FargateAmazon Web Services
 
Costruire Applicazioni Moderne con AWS
Costruire Applicazioni Moderne con AWSCostruire Applicazioni Moderne con AWS
Costruire Applicazioni Moderne con AWSAmazon Web Services
 
Come spendere fino al 90% in meno con i container e le istanze spot
Come spendere fino al 90% in meno con i container e le istanze spot Come spendere fino al 90% in meno con i container e le istanze spot
Come spendere fino al 90% in meno con i container e le istanze spot Amazon Web Services
 
Rendi unica l’offerta della tua startup sul mercato con i servizi Machine Lea...
Rendi unica l’offerta della tua startup sul mercato con i servizi Machine Lea...Rendi unica l’offerta della tua startup sul mercato con i servizi Machine Lea...
Rendi unica l’offerta della tua startup sul mercato con i servizi Machine Lea...Amazon Web Services
 
OpsWorks Configuration Management: automatizza la gestione e i deployment del...
OpsWorks Configuration Management: automatizza la gestione e i deployment del...OpsWorks Configuration Management: automatizza la gestione e i deployment del...
OpsWorks Configuration Management: automatizza la gestione e i deployment del...Amazon Web Services
 
Microsoft Active Directory su AWS per supportare i tuoi Windows Workloads
Microsoft Active Directory su AWS per supportare i tuoi Windows WorkloadsMicrosoft Active Directory su AWS per supportare i tuoi Windows Workloads
Microsoft Active Directory su AWS per supportare i tuoi Windows WorkloadsAmazon Web Services
 
Database Oracle e VMware Cloud on AWS i miti da sfatare
Database Oracle e VMware Cloud on AWS i miti da sfatareDatabase Oracle e VMware Cloud on AWS i miti da sfatare
Database Oracle e VMware Cloud on AWS i miti da sfatareAmazon Web Services
 
Crea la tua prima serverless ledger-based app con QLDB e NodeJS
Crea la tua prima serverless ledger-based app con QLDB e NodeJSCrea la tua prima serverless ledger-based app con QLDB e NodeJS
Crea la tua prima serverless ledger-based app con QLDB e NodeJSAmazon Web Services
 
API moderne real-time per applicazioni mobili e web
API moderne real-time per applicazioni mobili e webAPI moderne real-time per applicazioni mobili e web
API moderne real-time per applicazioni mobili e webAmazon Web Services
 
Database Oracle e VMware Cloud™ on AWS: i miti da sfatare
Database Oracle e VMware Cloud™ on AWS: i miti da sfatareDatabase Oracle e VMware Cloud™ on AWS: i miti da sfatare
Database Oracle e VMware Cloud™ on AWS: i miti da sfatareAmazon Web Services
 
Tools for building your MVP on AWS
Tools for building your MVP on AWSTools for building your MVP on AWS
Tools for building your MVP on AWSAmazon Web Services
 
How to Build a Winning Pitch Deck
How to Build a Winning Pitch DeckHow to Build a Winning Pitch Deck
How to Build a Winning Pitch DeckAmazon Web Services
 
Building a web application without servers
Building a web application without serversBuilding a web application without servers
Building a web application without serversAmazon Web Services
 
AWS_HK_StartupDay_Building Interactive websites while automating for efficien...
AWS_HK_StartupDay_Building Interactive websites while automating for efficien...AWS_HK_StartupDay_Building Interactive websites while automating for efficien...
AWS_HK_StartupDay_Building Interactive websites while automating for efficien...Amazon Web Services
 
Introduzione a Amazon Elastic Container Service
Introduzione a Amazon Elastic Container ServiceIntroduzione a Amazon Elastic Container Service
Introduzione a Amazon Elastic Container ServiceAmazon Web Services
 

Más de Amazon Web Services (20)

Come costruire servizi di Forecasting sfruttando algoritmi di ML e deep learn...
Come costruire servizi di Forecasting sfruttando algoritmi di ML e deep learn...Come costruire servizi di Forecasting sfruttando algoritmi di ML e deep learn...
Come costruire servizi di Forecasting sfruttando algoritmi di ML e deep learn...
 
Big Data per le Startup: come creare applicazioni Big Data in modalità Server...
Big Data per le Startup: come creare applicazioni Big Data in modalità Server...Big Data per le Startup: come creare applicazioni Big Data in modalità Server...
Big Data per le Startup: come creare applicazioni Big Data in modalità Server...
 
Esegui pod serverless con Amazon EKS e AWS Fargate
Esegui pod serverless con Amazon EKS e AWS FargateEsegui pod serverless con Amazon EKS e AWS Fargate
Esegui pod serverless con Amazon EKS e AWS Fargate
 
Costruire Applicazioni Moderne con AWS
Costruire Applicazioni Moderne con AWSCostruire Applicazioni Moderne con AWS
Costruire Applicazioni Moderne con AWS
 
Come spendere fino al 90% in meno con i container e le istanze spot
Come spendere fino al 90% in meno con i container e le istanze spot Come spendere fino al 90% in meno con i container e le istanze spot
Come spendere fino al 90% in meno con i container e le istanze spot
 
Open banking as a service
Open banking as a serviceOpen banking as a service
Open banking as a service
 
Rendi unica l’offerta della tua startup sul mercato con i servizi Machine Lea...
Rendi unica l’offerta della tua startup sul mercato con i servizi Machine Lea...Rendi unica l’offerta della tua startup sul mercato con i servizi Machine Lea...
Rendi unica l’offerta della tua startup sul mercato con i servizi Machine Lea...
 
OpsWorks Configuration Management: automatizza la gestione e i deployment del...
OpsWorks Configuration Management: automatizza la gestione e i deployment del...OpsWorks Configuration Management: automatizza la gestione e i deployment del...
OpsWorks Configuration Management: automatizza la gestione e i deployment del...
 
Microsoft Active Directory su AWS per supportare i tuoi Windows Workloads
Microsoft Active Directory su AWS per supportare i tuoi Windows WorkloadsMicrosoft Active Directory su AWS per supportare i tuoi Windows Workloads
Microsoft Active Directory su AWS per supportare i tuoi Windows Workloads
 
Computer Vision con AWS
Computer Vision con AWSComputer Vision con AWS
Computer Vision con AWS
 
Database Oracle e VMware Cloud on AWS i miti da sfatare
Database Oracle e VMware Cloud on AWS i miti da sfatareDatabase Oracle e VMware Cloud on AWS i miti da sfatare
Database Oracle e VMware Cloud on AWS i miti da sfatare
 
Crea la tua prima serverless ledger-based app con QLDB e NodeJS
Crea la tua prima serverless ledger-based app con QLDB e NodeJSCrea la tua prima serverless ledger-based app con QLDB e NodeJS
Crea la tua prima serverless ledger-based app con QLDB e NodeJS
 
API moderne real-time per applicazioni mobili e web
API moderne real-time per applicazioni mobili e webAPI moderne real-time per applicazioni mobili e web
API moderne real-time per applicazioni mobili e web
 
Database Oracle e VMware Cloud™ on AWS: i miti da sfatare
Database Oracle e VMware Cloud™ on AWS: i miti da sfatareDatabase Oracle e VMware Cloud™ on AWS: i miti da sfatare
Database Oracle e VMware Cloud™ on AWS: i miti da sfatare
 
Tools for building your MVP on AWS
Tools for building your MVP on AWSTools for building your MVP on AWS
Tools for building your MVP on AWS
 
How to Build a Winning Pitch Deck
How to Build a Winning Pitch DeckHow to Build a Winning Pitch Deck
How to Build a Winning Pitch Deck
 
Building a web application without servers
Building a web application without serversBuilding a web application without servers
Building a web application without servers
 
Fundraising Essentials
Fundraising EssentialsFundraising Essentials
Fundraising Essentials
 
AWS_HK_StartupDay_Building Interactive websites while automating for efficien...
AWS_HK_StartupDay_Building Interactive websites while automating for efficien...AWS_HK_StartupDay_Building Interactive websites while automating for efficien...
AWS_HK_StartupDay_Building Interactive websites while automating for efficien...
 
Introduzione a Amazon Elastic Container Service
Introduzione a Amazon Elastic Container ServiceIntroduzione a Amazon Elastic Container Service
Introduzione a Amazon Elastic Container Service
 

Embracing Change without Breaking the World - DEV319 - re:Invent 2017

  • 1. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Embracing Change Without Breaking The World J i m F l a n a g a n – S o f t w a r e E n g i n e e r – A W S C r y p t o g r a p h y K y l e T h o m s o n – S o f t w a r e E n g i n e e r – A W S S D K D E V 3 1 9 N o v e m b e r 3 0 , 2 0 1 7 AWS re:INVENT
  • 2. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Introduction • AWS has 90+ services and deploys API updates several times a week (often daily) • Backwards compatibility is necessary
  • 3. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Who are we? • API review bar-raisers • Experienced API reviewers and library designers • Responsible for quality of AWS APIs • Ensure backwards compatibility of API changes
  • 4. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Agenda • Definitions • What’s backwards compatibility and why is it important? • What’s an API (by way of example)? • Changing an API • What’s safe to do in the API? • How should we design our clients? • API constraints and validation • Client-side concerns • Exceptions • Undocumented API contracts • Sharing shapes • Backwards compatibility rules
  • 5. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Definitions
  • 6. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. How APIs evolve relative to clients API Client
  • 7. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. How APIs evolve relative to clients API Client API v2 Client v2
  • 8. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. How APIs evolve relative to clients API Client API v2 Client v2 API v3 Client v3 API v4 Client v4 API vN Client vN
  • 9. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  • 10. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. How APIs evolve relative to clients API Client API´ Client´
  • 11. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. How APIs evolve relative to clients Client API´ Client´
  • 12. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Anatomy of a Web API—resources Trip
  • 13. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Anatomy of a Web API—resources Trip travelers: [string] description: string … “Shape" “Member”
  • 14. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Anatomy of a Web API—resources Trip travelers: [string] description: string flight: Flight Flight airline: string status: string …
  • 15. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Anatomy of a Web API PutTrip GetTrip ListTrips
  • 16. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Anatomy of a Web API PUT /Trips GET /Trips/{id} GET /Trips
  • 17. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Anatomy of a Web API 123 GetTrip { “travelers”: [“Jim”], “description”: “re:Invent” }
  • 18. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Anatomy of a Web API 123 GetTrip { “travelers”: [“Jim”], “description”: “re:Invent” } Input shape
  • 19. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Anatomy of a Web API 123 GetTrip { “travelers”: [“Jim”], “description”: “re:Invent” }
  • 20. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Anatomy of a Web API 321 GetTrip ResourceNotFound
  • 21. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Summary of definitions • Resources—things that an API manages • Shape—some structure with members • Input shape—a top-level request shape passed to an operation • Output shape—a top-level response shape return from an operation • Error shape—a structure that represents an error response from an operation • Member—belongs to a shape represents some property • Operation—something the service exposes that can be invoked (e.g. getTrips)
  • 22. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Changing an API
  • 23. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding/removing Trip travelers: [string] description: string origin: string
  • 24. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding/removing Trip travelers: [string] description: string origin: string
  • 25. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding/removing Trip travelers: [string] description: string origin: string
  • 26. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding/removing Trip travelers: [string] description: string origin: string
  • 27. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding/removing Trip travelers: [string] description: string
  • 28. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding members public final class Trip { private final List<String> travelers; private final String description; public Trip(List<String> travelers, String description) { this.travelers = travelers; this.description = description; } public List<String> getTravelers() { return travelers; } public String getDescription() { return description; } }
  • 29. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding members List<String> travelers = Collections.singletonList("Jim"); Trip myTrip = new Trip(travelers, "re:Invent");
  • 30. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding/removing Trip travelers: [string] description: string origin: string
  • 31. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding members to the constructor public Trip(List<String> travelers, String description, String origin) { this.travelers = travelers; this.description = description; this.origin = origin; }
  • 32. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding members to the constructor public Trip(List<String> travelers, String description, String origin) { this.travelers = travelers; this.description = description; this.origin = origin; } Trip myTrip = new Trip(travelers, "re:Invent"); Won’t compile
  • 33. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Constructor overload public Trip(List<String> travelers, String description) { this(travelers, description, null); } public Trip(List<String> travelers, String description, String origin) { this.travelers = travelers; this.description = description; this.origin = origin; } Trip myTrip = new Trip(travelers, "re:Invent"); Trip myTrip = new Trip(travelers, "re:Invent”, “USA”);
  • 34. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. All constructor combinations public Trip(List<String> travelers, String description, String origin) public Trip(List<String> travelers, String description) public Trip(List<String> travelers) public Trip(String description, String origin) public Trip(String description) public Trip(List<String> travelers, String origin)
  • 35. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
  • 36. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. All constructor combinations public Trip(List<String> travelers, String description, String origin) public Trip(List<String> travelers, String description) public Trip(List<String> travelers) public Trip(String description, String origin) public Trip(String description) public Trip(List<String> travelers, String origin) public Trip(String origin)
  • 37. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. All constructor combinations public Trip(List<String> travelers, String description, String origin) public Trip(List<String> travelers, String description) public Trip(List<String> travelers) public Trip(String description, String origin) public Trip(String description) public Trip(List<String> travelers, String origin) public Trip(String origin) Clash!
  • 38. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Languages with default values
  • 39. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding members public final class Trip { private List<String> travelers; private String description; public Trip() { } public void setTravelers(List<String> travelers) { this.travelers = travelers; } public void setDescription(String description) { this.description = description; } /** getters omitted **/ }
  • 40. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding members public final class Trip { private List<String> travelers; private String description; public Trip() { } public void setTravelers(List<String> travelers) { this.travelers = travelers; } public void setDescription(String description) { this.description = description; } /** getters omitted **/ } Trip trip = new Trip(); trip.setTravelers(travelers); trip.setDescription("re:Invent");
  • 41. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding members public final class Trip { private List<String> travelers; private String description; private String origin; public Trip() { } public void setTravelers(List<String> travelers) { this.travelers = travelers; } public void setDescription(String description) { this.description = description; } public void setOrigin(String origin) { this.origin = origin; } }
  • 42. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding members public final class Trip { private List<String> travelers; private String description; private String origin; public Trip() { } public void setTravelers(List<String> travelers) { this.travelers = travelers; } public void setDescription(String description) { this.description = description; } public void setOrigin(String origin) { this.origin = origin; } } Models are mutable
  • 43. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding members public final class Trip { private final List<String> travelers; private final String description; private Trip(Builder builder) { this.travelers = builder.travelers; this.description = builder.description; } public static Builder builder() { return new Builder(); } public static class Builder { private List<String> travelers; private String description; public Builder travelers(List<String> travelers) { this.travelers = travelers; return this; } public Builder description(String description) { this.description = description; return this; } public Trip build() { return new Trip(this); } } }
  • 44. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding members public final class Trip { private final List<String> travelers; private final String description; private Trip(Builder builder) { this.travelers = builder.travelers; this.description = builder.description; } public static Builder builder() { return new Builder(); } public static class Builder { private List<String> travelers; private String description; public Builder travelers(List<String> travelers) { this.travelers = travelers; return this; } public Builder description(String description) { this.description = description; return this; } public Trip build() { return new Trip(this); } } } Members are final
  • 45. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding members public final class Trip { private final List<String> travelers; private final String description; private Trip(Builder builder) { this.travelers = builder.travelers; this.description = builder.description; } public static Builder builder() { return new Builder(); } public static class Builder { private List<String> travelers; private String description; public Builder travelers(List<String> travelers) { this.travelers = travelers; return this; } public Builder description(String description) { this.description = description; return this; } public Trip build() { return new Trip(this); } } } Constructor is private
  • 46. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding members public final class Trip { private final List<String> travelers; private final String description; private Trip(Builder builder) { this.travelers = builder.travelers; this.description = builder.description; } public static Builder builder() { return new Builder(); } public static class Builder { private List<String> travelers; private String description; public Builder travelers(List<String> travelers) { this.travelers = travelers; return this; } public Builder description(String description) { this.description = description; return this; } public Trip build() { return new Trip(this); } } } Trip trip = Trip.builder() .travelers(travelers) .description("re:Invent") .build();
  • 47. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding members public final class Trip { private final List<String> travelers; private final String description, origin; private Trip(Builder builder) { this.travelers = builder.travelers; this.description = builder.description; this.origin = builder.origin; } public static Builder builder() { return new Builder(); } public static class Builder { private List<String> travelers; private String description, origin; public Builder travelers(List<String> travelers) { this.travelers = travelers; return this; } public Builder description(String description) { this.description = description; return this; } public Builder origin(String origin) { this.origin = origin; return this; } public Trip build() { return new Trip(this); } } }
  • 48. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Constraints & Validation
  • 49. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding—caveats Trip travelers: [string] description: string origin: string destination: stringRequired
  • 50. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding—caveats Flight airline: string status: FlightStatusEnum …
  • 51. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding—caveats Requested RejectedBooked Terminal state Processing
  • 52. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding—caveats Requested Processing RejectedBooked Error
  • 53. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Adding—caveats Requested Processing … Review
  • 54. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Enumerations in code public final class Flight { private final String airline; private final FlightStatus status; private Flight(String airline, FlightStatus status) { this.airline = airline; this.status = status; } public String getAirline() { return airline; } public FlightStatus getStatus() { return status; } } public enum FlightStatus { REQUESTED, PROCESSING, BOOKED, REJECTED; }
  • 55. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Enumerations in code public final class Flight { private final String airline; private final String status; private Flight(String airline, String status) { this.airline = airline; this.status = status; } public String getAirline() { return airline; } public String getStatus() { return status; } } FlightStatus.valueOf(flight.getStatus());
  • 56. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Enumerations in code public enum FlightStatus { REQUESTED, PROCESSING, BOOKED, REJECTED, SDK_UNKNOWN; } public final class Flight { private final String airline; private final String status; public FlightStatus getStatus() { try { return FlightStatus.valueOf(status); } catch (IllegalArgumentException e) { return FlightStatus.SDK_UNKNOWN; } } }
  • 57. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Enumerations in code public enum FlightStatus { REQUESTED, PROCESSING, BOOKED, REJECTED, SDK_UNKNOWN; } public final class Flight { private final String airline; private final String status; public FlightStatus getStatus() { try { return FlightStatus.valueOf(status); } catch (IllegalArgumentException e) { return FlightStatus.SDK_UNKNOWN; } } public String getStatusAsString() { return status; } } switch(flight.getStatus()) { case BOOKED: System.out.println("Yay!"); case SDK_UNKNOWN: System.out.println("Unknown value: " + flight.getStatusAsString()); }
  • 58. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Client side validation public final class Trip { private final List<String> travelers; private final String description; private Trip(Builder builder) { this.travelers = Validate.hasSize(builder.travelers, 1); this.description = Validate.notNull(builder.description); } @NotNull public List<String> travelers() { return travelers; } @NotNull public String description() { return description; } } fun descriptionLength(): Int = trip.description().length
  • 59. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Client side validation public final class Trip { private final List<String> travelers; private final String description; private Trip(Builder builder) { this.travelers = Validate.hasSize(builder.travelers, 1); this.description = builder.description; } @NotNull public List<String> travelers() { return travelers; } @NotNull public String description() { return description; } } fun descriptionLength(): Int = trip.description()?.length
  • 60. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Source Compatibility public interface TripClient { void putTrip(PutTripRequest request); GetTripResponse getTrip(GetTripRequest request); GetTripsResponse getTrips(); } TripClient tripClient = ...; tripClient.putTrip(putTripRequest); response = tripClient.getTrip(getTripRequest);
  • 61. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Source Compatibility public interface TripClient { PutTripResponse putTrip(PutTripRequest request); GetTripResponse getTrip(GetTripRequest request); GetTripsResponse getTrips(); } TripClient tripClient = ...; tripClient.putTrip(putTripRequest); response = tripClient.getTrip(getTripRequest);
  • 62. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Binary Compatibility public interface TripClient { void putTrip(PutTripRequest trip); } public interface TripClient { PutTripResponse putTrip(PutTripRequest trip); } TripClient tripClient = ...; tripClient.putTrip(putTripRequest); response = tripClient.getTrip(getTripRequest); NoSuchMethod Exception
  • 63. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Exceptions
  • 64. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Exceptions PutFlight: Input: PutFlightRequest Output: Flight | ValidationError | UnknownAirportError
  • 65. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Exceptions PutFlightRequest airline: string date: dateTime ValidationError InvalidDateError
  • 66. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Exceptions ValidationError message: string field: string validationType: VTypeEnum
  • 67. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Undocumented API Contracts
  • 68. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Undocumented API contracts Hyrum’s Law–With sufficient number of users of an API, it does not matter what you promise in the contract, all observable behaviors of your system will be depended on by somebody
  • 69. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. ”ListTripsRequest” : { ”nextToken” … } ”ListTripsResult” : { ”nextToken” … } Undocumented API contracts
  • 70. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. ”ListTripsRequest” : {} ”ListTripsRequest” : { ”nextToken” : “page2” } ”ListTripsResult” : { “items” : [ … ], ”nextToken” : ”page2” } Undocumented API contracts
  • 71. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Undocumented API contracts ”ListTripsRequest” : { ”nextToken” : “page2000” }
  • 72. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. ”ListTripsRequest” : {} ”ListTripsRequest” : { ”nextToken” : “page2” } ”ListTripsResult” : { “items” : [ … ], ”nextToken” : ”10-20” } Undocumented API contracts
  • 73. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. ”ListTripsRequest” : {} ”ListTripsRequest” : { ”nextToken” : “page2” } ”ListTripsResult” : { “items” : [ … ], ”nextToken” : ”10-20” } Undocumented API contracts
  • 74. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Undocumented API contracts ”ListTripsResponse” : { “items”: [ … ], ”nextToken” : “cGFnZTIK” }
  • 75. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Sharing Shapes
  • 76. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Sharing shapes UpdateFlight: Input: Flight Output: Flight
  • 77. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Sharing shapes Flight airline: string status: FlightStatusEnum lastModified: Date
  • 78. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Sharing shapes UpdateFlight: Input: Flight Output: Flight
  • 79. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Sharing shapes UpdateFlight: Input: UpdateFlightRequest Output: Flight
  • 80. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Backwards Compatibility Rules
  • 81. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. The Good (Dos) API • Adding members/shapes • Adding intermediate (non-terminal) workflow states • Adding details to exceptions (error codes) • Adding new opt-in exceptions • Loosening constraints (e.g. increase max length) Client • Forward compatible (support all of the above) • Focus on discoverability The Bad (Don’ts) API • Removing/renaming members/shapes • Changing the type of members • Adding new terminal workflow states • Adding exceptions without opt-in • Tightening constraints (e.g. decrease max-length) Client • Validating API constraints The Rules
  • 82. © 2017, Amazon Web Services, Inc. or its Affiliates. All rights reserved. Thank you! D E V 3 1 9