Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Haifengl Smile Model Discovery REST API

From Leeroopedia


Overview

The Model Discovery REST API provides two HTTP endpoints for enumerating deployed models and inspecting individual model metadata. These endpoints are implemented in InferenceResource (the JAX-RS resource class) and return data structures defined in ModelMetadata. Clients use these endpoints to discover available models and their input contracts before sending prediction requests.

Source Location

Class Location
InferenceResource (list + get) serve/src/main/java/smile/serve/InferenceResource.java (Lines 51-62)
ModelMetadata serve/src/main/java/smile/serve/ModelMetadata.java (Lines 29-54)
InferenceService (backing logic) serve/src/main/java/smile/serve/InferenceService.java

Import Statements

N/A -- these are REST endpoints consumed via HTTP. For server-side development:

import smile.serve.InferenceResource;
import smile.serve.ModelMetadata;

External Dependencies

Dependency Annotation/Class Purpose
JAX-RS (Jakarta REST) @GET Marks methods as HTTP GET handlers
JAX-RS @Path Defines the URL path for the resource
JAX-RS @Produces(MediaType.APPLICATION_JSON) Specifies JSON response content type
JAX-RS @PathParam Extracts path parameters from the URL
Jackson ObjectMapper (implicit via Quarkus) Serializes Java objects to JSON responses

Type

API Doc

REST Endpoints

List Models

Property Value
Method GET
Path /api/v1/models
Produces application/json
Response JSON array of model ID strings
Errors None (returns empty array if no models loaded)

Java implementation:

@GET
@Produces(MediaType.APPLICATION_JSON)
public List<String> list() {
    return service.models();
}

Example request with curl:

curl -s http://localhost:8080/api/v1/models

Example response:

["iris-classifier-2", "boston-regression-1", "wine-gbm-3"]

Get Model Metadata

Property Value
Method GET
Path /api/v1/models/{id}
Path Parameter id -- the model identifier (e.g., "iris-classifier-2")
Produces application/json
Response ModelMetadata JSON object
Errors 404 Not Found if the model ID does not exist

Java implementation:

@GET
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public ModelMetadata get(@PathParam("id") String id) {
    return service.getModel(id).metadata();
}

Example request with curl:

curl -s http://localhost:8080/api/v1/models/iris-classifier-2

Example response:

{
  "id": "iris-classifier-2",
  "algorithm": "random-forest",
  "schema": {
    "sepal_length": {"type": "double", "nullable": false},
    "sepal_width": {"type": "double", "nullable": false},
    "petal_length": {"type": "double", "nullable": false},
    "petal_width": {"type": "double", "nullable": false}
  },
  "tags": {
    "id": "iris-classifier",
    "version": "2"
  }
}

ModelMetadata Structure

public class ModelMetadata {
    /** Data type descriptor for a schema field. */
    public record Type(String type, boolean nullable) {}

    /** The model id (e.g., "iris-classifier-2"). */
    public String id;

    /** The learning algorithm (e.g., "random-forest"). */
    public String algorithm;

    /** Input data schema: maps field name -> Type(datatype, nullable). */
    public Map<String, Type> schema;

    /** User-defined model metadata tags. */
    public Properties tags;
}

Constructor Logic

The ModelMetadata constructor extracts metadata directly from the Model object:

public ModelMetadata(String id, Model model) {
    this.id = id;
    this.algorithm = model.algorithm();
    this.schema = new TreeMap<>();
    this.tags = model.tags();
    for (var field : model.schema().fields()) {
        schema.put(field.name(),
            new Type(field.dtype().name(), field.dtype().isNullable()));
    }
}

This iterates over the model's StructType schema (which excludes the response variable), extracting each field's name, data type name, and nullability flag. The schema is stored in a TreeMap for alphabetical ordering in the JSON output.

URL Routing

The base path for all model endpoints is configured in application.properties:

quarkus.rest.path=/api/v1

The InferenceResource class is annotated with @Path("/models"), so the full paths become:

Endpoint Full URL
List models GET /api/v1/models
Get metadata GET /api/v1/models/{id}
Predict POST /api/v1/models/{id}
Stream predict POST /api/v1/models/{id}/stream

Error Handling

When a client requests metadata for a non-existent model, the InferenceService.getModel() method throws a jakarta.ws.rs.NotFoundException:

public InferenceModel getModel(String id) throws NotFoundException {
    var model = models.get(id);
    if (model == null) throw new NotFoundException(id);
    return model;
}

Quarkus automatically maps this exception to an HTTP 404 response with the model ID in the error message.

Example error response:

curl -v http://localhost:8080/api/v1/models/nonexistent-model
# HTTP/1.1 404 Not Found

Typical Client Workflow

A client interacts with the discovery API in this sequence:

  1. Enumerate models: GET /api/v1/models to discover available model IDs.
  2. Inspect metadata: GET /api/v1/models/{id} to learn the input schema for the desired model.
  3. Validate input: Use the schema to validate or construct the request payload.
  4. Send prediction: POST /api/v1/models/{id} with the feature data.

Related

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment