Part 2: Setting Up APIs for Function Calling
For our Gemini agent to perform actions in the real world (like checking a calendar), it needs a set of well-defined tools. These tools are our backend APIs. We will use Spring Boot to create a simple, secure, and scalable backend. This article guides you through understanding, running, and deploying a Spring Boot-based REST API for managing appointments. The application uses Google Firestore for data persistence and is designed for a seamless, automated deployment to Google Cloud Run using Cloud Build.
Objective
The appointment-api
is a backend service that provides RESTful endpoints for a simple
appointment scheduling system. Its core functionalities include:
- User Management: Create and retrieve user profiles.
- Appointment Scheduling: Create available appointment slots and view them.
- Appointment Confirmation: Book an available slot and receive a confirmation.
It's built to be cloud-native, leveraging Google Cloud's serverless offerings for scalability and ease of management.
Tech Stack
- Framework: Java 17 & Spring Boot 3
- Build Tool: Maven
- Database: Google Firestore (in Native Mode)
- Deployment: Docker, Google Cloud Run, Google Cloud Build
- API Documentation: SpringDoc (OpenAPI 3)
Prerequisites
Before you begin, ensure you have the following tools installed and configured.
Local Tools
- Java 17+: The project is built on Java 17.
- Maven: To manage dependencies and run the project.
- Docker: To containerize the application.
- Google Cloud SDK: To interact with your Google Cloud project. Installation Guide.
Google Cloud Setup
-
GCP Project: Create a new Google Cloud Project or use an existing one. Make sure billing is enabled.
-
Set Project ID: Set your project ID in your terminal to simplify
gcloud
commands.export PROJECT_ID="your-gcp-project-id" gcloud config set project $PROJECT_ID
-
Enable APIs: Enable the necessary APIs for Cloud Run, Cloud Build, and Firestore.
gcloud services enable run.googleapis.com \ cloudbuild.googleapis.com \ firestore.googleapis.com \ iam.googleapis.com
-
Create Firestore Database: Create a Firestore database in Native mode in a region of your choice (e.g.,
us-central1
).
Setup & Running Locally
Running the application on your local machine is a great way to test and develop.
-
Clone the Repository
git clone <your-repository-url> cd appointment-api
-
Authenticate for Local Development
The application uses Application Default Credentials (ADC) to connect to Firestore. Log in with your user account to provide credentials for local runs.gcloud auth application-default login
Enable Swagger UI for Local Testing
The Swagger UI is disabled by default inapplication.properties
. For local development, you can enable it by running with thelocal
profile, which is defined insrc/main/resources/application-local.properties
.Run the Application
Use the Maven wrapper to run the application with thelocal
profile active../mvnw spring-boot:run -Dspring-boot.run.profiles=local
The API will be running at
http://localhost:8080
.Accessing the API Locally
- Swagger UI:
http://localhost:8080/appointment/swagger.html
- OpenAPI Spec:
http://localhost:8080/appointment/api-docs
- Health Check:
http://localhost:8080/appointment/actuator/health
Deployment to Google Cloud Run
We will use Google Cloud Build to automate the process of building the container image and deploying it to Cloud Run. This is the recommended approach for CI/CD.
The One-Command Deploy
The
cloudbuild.yaml
file in the root of the project defines the entire build and deployment pipeline. To trigger it, simply run the following command from your project's root directory:gcloud builds submit .
What's Happening Behind the Scenes?
When you run
gcloud builds submit
, here's the process that unfolds:- Upload: Your code is packaged and uploaded to a Cloud Storage bucket.
- Build: Cloud Build starts a new build process based on
cloudbuild.yaml
. - Step 1 - Docker Build: Cloud Build uses the provided
Dockerfile
to build your Spring Boot application into a container image. - Step 2 - Docker Push: The newly built image is tagged and pushed to Google Container
Registry (GCR) at
gcr.io/your-project-id/appt-api
. - Step 3 - GCloud Deploy: Cloud Build uses the
gcloud
builder to deploy the image from GCR to Cloud Run. It configures the service to be publicly accessible (--allow-unauthenticated
).
Post-Deployment
-
Find Your Service URL
After the deployment succeeds, Cloud Build will print the URL of your service. You can also retrieve it anytime with:gcloud run services describe appointment-api \ --platform managed \ --region us-central1 \ --format "value(status.url)"
-
Testing the Deployed API
Replace[SERVICE_URL]
with the URL you obtained above.-
Health Check:
curl [SERVICE_URL]/appointment/actuator/health
You should see a response like
{"status":"UP"}
. -
Create a User:
curl -X POST "[SERVICE_URL]/appointment/users" \ -H "Content-Type: application/json" \ -d '{"memberId": "user001", "firstName": "Jane", "lastName": "Doe", "email": "jane.doe@example.com"}'
-
Get a User:
curl [SERVICE_URL]/appointment/users/user001
-
Troubleshooting
If the deployment step fails with an IAM policy error, it might mean the Cloud Build service account doesn't have permission to deploy to Cloud Run or act as an IAM user. You may need to grant the
Cloud Build Service Account
theCloud Run Admin
andService Account User
roles in the IAM console.If the service deploys but is not publicly accessible, you can set the IAM policy manually:
gcloud run services add-iam-policy-binding appointment-api \ --region=us-central1 \ --member="allUsers" \ --role="roles/run.invoker"
API Endpoints
The following endpoints are available (assuming standard REST controllers are mapped to the broker/implementation classes).
POST /users
: Creates a new user.GET /users/{memberId}
: Retrieves a user by their member ID.POST /appointments/slots
: Creates a new schedule of appointment slots.GET /appointments/slots
: Retrieves all available appointment schedules.POST /appointments/confirm
: Confirms/books an appointment for a user.
The API specification is available at
[SERVICE_URL]/appointment/api-docs
.
Defining the Tool Specification
The core of function calling is providing the AI model with a clear "schema" of the functions it can invoke. This includes the function name, a description of what it does, and the parameters it accepts.
We will create two main endpoints:
GET /api/appointments/available-slots
: Checks for open appointment times on a given date.POST /api/appointments/book
: Books an appointment for a specific date and time slot.
Spring Boot Implementation Example
Here is a simplified example of what the controller for available slots might look like:
@RestController @RequestMapping("/api/appointments") public class AppointmentController { @GetMapping("/available-slots") public ResponseEntity<List<String>> getAvailableSlots(@RequestParam String date) { // In a real application, you would query a database. // For this example, we return a mock list. System.out.println("Checking availability for: " + date); List<String> slots = List.of("10:00 AM", "2:00 PM", "4:00 PM"); return ResponseEntity.ok(slots); } }
Lets start to set up the Google Gemini AI Agent in the next part of this series.