Skip to content

Add required properties to OpenAPI schemas#45

Merged
thibauult merged 1 commit intomainfrom
fix/add-required-properties
Feb 7, 2026
Merged

Add required properties to OpenAPI schemas#45
thibauult merged 1 commit intomainfrom
fix/add-required-properties

Conversation

@thibauult
Copy link
Collaborator

@thibauult thibauult commented Feb 6, 2026

Summary

This PR adds required property declarations to OpenAPI schemas based on the official Hue CLIP API documentation.

Problem

As reported in #44, many object schemas were missing required properties. This caused code generators to treat all fields as optional, leading to clunky generated models (e.g., Option<String> instead of String in Rust).

Solution

Added required declarations to schemas by cross-referencing with the official Hue API documentation (onlinedoc.html).

Updated schemas:

Common schemas:

  • Resource.yaml: Added required: [type, id]
  • ResourceIdentifier.yaml: Added required: [rid, rtype]
  • ResourceOwned.yaml: Added required: [owner]
  • GamutPosition.yaml: Added required: [x, y]
  • On.yaml: Added required: [on]
  • Dimming.yaml: Added required: [brightness]
  • Color.yaml: Added required: [xy]
  • error.yaml: Added required to ErrorResponse and Error
  • ApiResponse.yaml: Added required: [errors, data]

Resource Get schemas:

  • RoomGet, DeviceGet, SceneGet, LightGet, MotionGet, BridgeGet, BridgeHomeGet, TemperatureGet, DevicePowerGet, LightLevelGet, ActionGet, ProductData

Validation

  • ✅ Spec passes redocly lint
  • ✅ Generated Rust client shows correct non-optional types for required fields

Fixes #44

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Corrected typo in motion sensor schema description.
    • Clarified bridge identifier description.
  • Chores

    • Updated .gitignore configuration.
  • Validation & Schema Updates

    • Enhanced API schema validation by making core fields mandatory across resource definitions.
    • Added new device and light properties: identify (visual identification trigger) and service_id.
    • Introduced function property to light metadata with options: functional, decorative, mixed, unknown.
    • Standardized required field enforcement across bridge, device, room, scene, and sensor schemas for improved data consistency.

This change adds 'required' property declarations to schemas based on
the official Hue CLIP API documentation.

Changes include:
- Common schemas: Resource, ResourceIdentifier, ResourceOwned,
  GamutPosition, On, Dimming, Color, error, ApiResponse
- Resource Get schemas: RoomGet, DeviceGet, SceneGet, LightGet,
  MotionGet, BridgeGet, BridgeHomeGet, TemperatureGet, DevicePowerGet,
  LightLevelGet, ActionGet, ProductData

This ensures code generators produce properly typed models with
non-optional fields where the API guarantees their presence.

Fixes #44

Co-Authored-By: Warp <agent@warp.dev>
@coderabbitai
Copy link

coderabbitai bot commented Feb 6, 2026

📝 Walkthrough

Walkthrough

This pull request systematically adds required field constraints across 22 schema files in the OpenHue API specification, making previously optional properties mandatory to align with documented API behavior. Changes include adding required lists to common schemas, device schemas, sensor schemas, room schemas, and scene schemas, plus one .gitignore update.

Changes

Cohort / File(s) Summary
Configuration
.gitignore
Added onlinedoc.html to IntelliJ HTTP Client section.
Common Schemas
src/common/ApiResponse.yaml, src/common/Color.yaml, src/common/Dimming.yaml, src/common/GamutPosition.yaml, src/common/On.yaml, src/common/Resource.yaml, src/common/ResourceIdentifier.yaml, src/common/ResourceOwned.yaml, src/common/error.yaml
Added required lists to mark fields as mandatory: errors and data in ApiResponse; xy in Color; brightness in Dimming; x and y in GamutPosition; on in On; type and id in Resource; rid and rtype in ResourceIdentifier; owner in ResourceOwned; errors in ErrorResponse and description in Error.
Bridge Schemas
src/bridge/schemas/BridgeGet.yaml, src/bridge_home/schemas/BridgeHomeGet.yaml
Added required lists: bridge_id and time_zone in BridgeGet (with clarified bridge_id description); children and services in BridgeHomeGet.
Device Schemas
src/device/schemas/DeviceGet.yaml, src/device/schemas/ProductData.yaml, src/device_power/schemas/DevicePowerGet.yaml
Added required lists and new properties: DeviceGet requires product_data, metadata, identify, services and adds identify property; ProductData requires six fields (model_id, manufacturer_name, product_name, product_archetype, certified, software_version); DevicePowerGet requires power_state and updates root description from "bridge" to "device".
Sensor & Light Schemas
src/light/schemas/LightGet.yaml, src/light_level/schemas/LightLevelGet.yaml, src/motion/schemas/MotionGet.yaml, src/temperature/schemas/TemperatureGet.yaml
Added required lists across sensor and light schemas: LightGet requires metadata, identify, service_id, on, mode and adds identify and service_id properties; LightLevelGet requires enabled, light, light_level, light_level_valid; MotionGet requires enabled, motion, motion_valid (fixed typo: "ture" → "true"); TemperatureGet requires enabled, temperature, temperature_valid.
Room & Scene Schemas
src/room/schemas/RoomGet.yaml, src/scene/schemas/ActionGet.yaml, src/scene/schemas/SceneGet.yaml
Added required lists: RoomGet requires children, services, metadata with nested name, archetype; ActionGet restructured to require target and simplified action object (replaced multi-field action with single effect reference); SceneGet requires actions, metadata, group, speed, auto_dynamic, status.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Behold! The schemas stand tall and strong,
With required fields where they belong,
No more null surprises in the night,
Each property promised, typed just right! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main objective of the PR: adding required property declarations to OpenAPI schemas as evidenced by all file changes.
Linked Issues check ✅ Passed All code changes directly address issue #44 by adding required property declarations to schemas based on Hue API documentation, enabling code generators to produce correctly-typed models with non-optional fields.
Out of Scope Changes check ✅ Passed The .gitignore addition for onlinedoc.html is a minor in-scope change supporting documentation reference; all other changes directly implement the required properties objective from issue #44.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/add-required-properties

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@thibauult
Copy link
Collaborator Author

thibauult commented Feb 6, 2026

Hey @flrgh, here's the src/models/room_get.rs after adding the right required properties:

use crate::models;
use serde::{Deserialize, Serialize};

#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct RoomGet {
    /// Type of the supported resources
    #[serde(rename = "type")]
    pub r#type: String,
    /// Unique identifier representing a specific resource instance
    #[serde(rename = "id")]
    pub id: String,
    /// Clip v1 resource identifier
    #[serde(rename = "id_v1", skip_serializing_if = "Option::is_none")]
    pub id_v1: Option<String>,
    /// Child devices/services to group by the derived group
    #[serde(rename = "children")]
    pub children: Vec<models::ResourceIdentifier>,
    /// References all services aggregating control and state of children in the group. This includes all services grouped in the group hierarchy given by child relation. This includes all services of a device grouped in the group hierarchy given by child relation. Aggregation is per service type, ie every service type which can be grouped has a corresponding definition of grouped type. Supported types: – grouped_light 
    #[serde(rename = "services")]
    pub services: Vec<models::ResourceIdentifier>,
    #[serde(rename = "metadata")]
    pub metadata: Box<models::RoomGetAllOfMetadata>,
}

impl RoomGet {
    pub fn new(r#type: String, id: String, children: Vec<models::ResourceIdentifier>, services: Vec<models::ResourceIdentifier>, metadata: models::RoomGetAllOfMetadata) -> RoomGet {
        RoomGet {
            r#type,
            id,
            id_v1: None,
            children,
            services,
            metadata: Box::new(metadata),
        }
    }
}

You can check the codegen from this PR using this ephemeral spec link.

Also it's occurring to me that changing properties from non-required to required could be considered a breaking change by consumers of the spec (?).

That will indeed be seen as a breaking change for existing consumers, but I am convinced that this is for the good of the project!

@flrgh
Copy link
Contributor

flrgh commented Feb 7, 2026

Nicely done! I think this is a good improvement for the auto-generated resource models.

@thibauult thibauult merged commit 5548942 into main Feb 7, 2026
5 checks passed
@thibauult thibauult deleted the fix/add-required-properties branch February 7, 2026 21:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Many object schemas are missing required properties

2 participants