Java – How to build rest calls dynamically to interface with different APIs

design-patternsjavaproducer-consumerreflection

Lets say I am building an application where clients can book bus tickets. The only thing they do is select, origin, destination and the type of service (express or standard). The system will then book the ticket against the right bus company api. The user does not need to chose service provider as it has already been negotiated by the hotel manager with the different bus companies.
The main purpose is to avoid changing existing code if a new hotel manager wants to add, remove or to change the bus company for a service provider.

For instance:

consumer: Hotel 1  
type of service: express  
service provider: Bus Co. A

consumer: Hotel 1   
type of service: standard  
service provider: Bus Co. B

consumer: Hotel 2  
type of service: express  
service provider: Bus Co. A

...

Each provider has its own API for booking and I need to generate the call and the payload in run time.

This is what I thought of doing:

OPTION 1 Store rest call details as a template in a database table as string with placeholders

contract (hotel name, type of service, api call url, payload)

Payload would be stored as text with placeholders.

Example:
contrat table info:

"Hilton New York", "express", "http://api.buscoA.com/book-ticket", "{origin:<origin>, destination:<destination>, service: expr}"
"Hilton New York", "standard", "http://api.busB.com/book", "{start:<origin>, end:<destination>, service_type: standard}"

OPTION 2 Store rest call details as a template in a database table and instantiate the rest call using a class through reflection

contract (hotel name, type of service, api call url, api class name)

And a class for each api will be created and I can instantiate and I can instantiate it through reflection using the table "class name" value

Example:

"Hilton New York", "express", "http://api.buscoA.com/book-ticket", "BusCompanyAApi"

Then I will have to create a class for each api and instantiate the object on demand by reflection using the class name stored in the database (BusCompanyAApi)

  • Is either option 1 or 2 a valid way to do this?
  • Is there a design pattern I could use?

NOTE: I am using java

Best Answer

Why wouldn't you just use a map of service providers by name? It'd be like the command pattern:

HotelServices.get(serviceProviderName)
    .handleService(serviceName, consumer);
Related Topic