This module is a Spring Boot application that serves as the backend API server for the Expedia Group SDK exemplar. It provides both REST and GraphQL endpoints for a fictional hotel booking system and serves as the foundation for SDK generation and testing.
The exemplar-server serves multiple purposes within the SDK ecosystem:
- API Reference Implementation: Demonstrates how to build APIs that are suitable for SDK generation
- OpenAPI Specification Source: Generates OpenAPI 3.1 specifications from Spring Boot code for REST SDK generation
- GraphQL Schema Provider: Provides a complete GraphQL schema and resolvers for GraphQL SDK examples
- Development Server: Enables testing and development of generated SDKs in a controlled environment
The server implements a simple hotel booking API with search, booking management, and CRUD operations.
The server provides comprehensive REST and GraphQL APIs for hotel booking operations:
| Endpoint | Method | Description | Operation ID |
|---|---|---|---|
/api/v1/hotels |
GET | Search hotels with optional city and price filters | search-hotel |
/api/v1/hotels/{id} |
GET | Get hotel details by ID | get-hotel-by-id |
/api/v1/bookings |
GET | Retrieve all bookings | get-all-bookings |
/api/v1/bookings |
POST | Create a new hotel booking | create-booking |
/api/v1/bookings/{confirmationNumber} |
GET | Get booking by confirmation number | get-booking-by-confirmation-number |
/api/v1/bookings/{confirmationNumber} |
PUT | Update an existing booking | update-booking |
/api/v1/bookings/{confirmationNumber} |
DELETE | Delete a booking | delete-booking |
Queries:
hotels(city: String, maxPrice: BigDecimal): [Hotel!]!- Search hotelshotel(id: ID!): Hotel- Get hotel by IDbookings: [Booking!]!- Get all bookingsbooking(confirmationNumber: String!): Booking- Get booking by confirmation number
Mutations:
createBooking(input: BookingInput!): Booking!- Create a new bookingupdateBooking(confirmationNumber: String!, input: BookingUpdateInput!): Booking!- Update existing booking
This simple Spring Boot application is built using modern Kotlin practices and follows the standard Spring boot architecture.
Refer to the build.gradle.kts build file for complete configuration details.
| Configuration | Description |
|---|---|
| Spring Boot | Uses Spring Boot 3 with Spring Web and Spring GraphQL starters |
| OpenAPI Generation | Integrates springdoc-openapi for automatic OpenAPI spec generation |
| Kotlin Support | Built with Kotlin and Spring Kotlin plugin |
| GraphQL | Includes Spring GraphQL starter for schema-first GraphQL implementation |
| Documentation | Swagger UI available at /swagger-ui.html for REST API testing |
| GraphQL Playground | GraphiQL interface available at /graphiql for interactive GraphQL testing |
| Package | Description |
|---|---|
controller.rest |
REST controllers implementing the hotel booking API endpoints |
controller.graphql |
GraphQL controllers with query and mutation resolvers |
service |
Business logic layer for hotel and booking operations |
repository |
Data access layer with in-memory storage for demo purposes |
model |
Domain models (Hotel, Booking, GuestInfo, etc.) with validation annotations |
exception |
Custom exceptions and global exception handling |
graphql |
GraphQL-specific input types and scalar configurations |
| File | Description |
|---|---|
application.properties |
Spring Boot application configuration |
schema.graphqls |
GraphQL schema definition with types, queries, and mutations |
- Java 17 or higher
- Gradle 8.x (included via wrapper)
Navigate to the exemplar module root and start the server:
cd exemplar
./gradlew :exemplar-server:bootRunThe server will start on http://localhost:8080 with the following interfaces:
- REST API Base URL:
http://localhost:8080/api/v1 - Swagger UI:
http://localhost:8080/swagger-ui.html- Interactive REST API documentation and testing - GraphQL Endpoint:
http://localhost:8080/graphql - GraphiQL Interface:
http://localhost:8080/graphiql- Interactive GraphQL query editor
- Open
http://localhost:8080/swagger-ui.html - Explore available endpoints
- Test hotel search:
GET /api/v1/hotels?city=New York&maxPrice=300 - Create a booking using the
POST /api/v1/bookingsendpoint
- Open
http://localhost:8080/graphiql - Try a hotel search query:
query {
hotels(city: "New York", maxPrice: 300.00) {
id
name
location {
city
}
pricePerNight
}
}To generate or update the OpenAPI specification for SDK generation:
./gradlew :exemplar-server:generateOpenApiDocsThis will:
- Start the server if not already running
- Fetch the OpenAPI specification from
/v3/api-docs.yaml - Save it as
openapi.yamlin theexemplar-sdk-restdirectory - Stop the server
The server implements a complete hotel booking domain with the following key entities:
- Properties: ID, name, description, location, price per night, amenities, star rating, check-in/out times
- Features: Search by city and maximum price filter
- Properties: Confirmation number, status, hotel reference, dates, guest count, guest info, total price, timestamps
- Status: PENDING, CONFIRMED, CANCELLED, COMPLETED
- Operations: Create, read, update, delete
- Properties: Address, city, state, country, postal code, latitude, longitude
- Usage: Embedded in Hotel entities for geographic information
- Properties: First name, last name, email, phone number
- Validation: Required fields with format validation
exemplar-sdk-rest: Generated REST client SDK that consumes this server's OpenAPI specificationexemplar-sdk-graphql: GraphQL client SDK that uses this server's GraphQL schemaexemplar-playground-java: Testing and demonstration module that exercises both generated SDKs against this serverexpediagroup-sdk-core: Foundation module providing core SDK abstractionsexpediagroup-sdk-openapi-plugin: Gradle plugin used to generate REST SDKs from this server's OpenAPI spec
The server follows a code-first approach where:
- API endpoints are implemented in Spring Boot controllers
- OpenAPI specifications are automatically generated from the code
- GraphQL schemas are manually maintained but validated against resolvers
- Client SDKs are generated from these specifications
To adapt this server for your own API:
- Modify the domain models in the
modelpackage - Update controllers to match your API design
- Adjust the GraphQL schema as needed
- Implement persistent storage if required
- Regenerate OpenAPI specs and update SDK dependencies