Skip to content

REST API: simplify json response by removing result wrapper (BC) #22299

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

andig
Copy link
Member

@andig andig commented Jul 10, 2025

Simplify HTTP JSON response format. Remove "result": {} wrapper.

Example GET /api/state

before

{
  "result": {
    "loadpoints": [...],
    ...
  }
}

after

{
  "loadpoints": [...],
  ...
}

TODO

@andig andig requested a review from naltatis July 10, 2025 19:42
@andig andig added infrastructure Basic functionality needs documentation Triggers issue creation in evcc-io/docs labels Jul 10, 2025
@andig andig marked this pull request as draft July 10, 2025 19:43
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @andig - I've reviewed your changes - here's some feedback:

  • This change breaks client contracts by removing the result wrapper, so please bump the API version or add a migration note to alert consumers of the new response format.
  • Make sure you update and regenerate the OpenAPI spec (and any MCP artifacts) before merging so the docs match the new JSON responses.
  • Double-check that all downstream code (including website components and integrations) has been updated to use response.data instead of response.data.result.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- This change breaks client contracts by removing the `result` wrapper, so please bump the API version or add a migration note to alert consumers of the new response format.
- Make sure you update and regenerate the OpenAPI spec (and any MCP artifacts) before merging so the docs match the new JSON responses.
- Double-check that all downstream code (including website components and integrations) has been updated to use `response.data` instead of `response.data.result`.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@andig
Copy link
Member Author

andig commented Jul 10, 2025

Make sure you update and regenerate the OpenAPI spec (and any MCP artifacts) before merging so the docs match the new JSON responses.

Schlaubi ;)

@andig
Copy link
Member Author

andig commented Jul 10, 2025

@naltatis integration hab ich wohl verdaddelt- dass das dann 17 Minuten läuft ist aber auch nicht schön?

@naltatis naltatis changed the title API: simplify json response by removing `result wrapper API: simplify json response by removing result wrapper (BC) Jul 10, 2025
@naltatis
Copy link
Member

dass das dann 17 Minuten läuft ist aber auch nicht schön?

ich schau mir die Timeouts mal an.

@StefanSchoof
Copy link
Contributor

@TheNinth7 Ich denke dieser PR wird für deine Garmin App Breaking.

@andig
Copy link
Member Author

andig commented Jul 11, 2025

No hurry, lets see if we can get this working first and then prepare transition.

@TheNinth7
Copy link

@TheNinth7 Ich denke dieser PR wird für deine Garmin App Breaking.

Ja, Danke für den Hinweis, werde die App entsprechend vorbereiten!

@naltatis naltatis changed the title API: simplify json response by removing result wrapper (BC) REST API: simplify json response by removing result wrapper (BC) Jul 11, 2025
@marq24
Copy link
Contributor

marq24 commented Jul 11, 2025

... currently the existence of a result object (in json response) is a true indication (in the ha-evcc), that there had been no other issues/errors with the request/response...

So when this result container object will be removed, at least the possible error evaluation & handling will become more complex...

@Maschga
Copy link
Contributor

Maschga commented Jul 11, 2025

currently the existence of a result object (in json response) is a true indication (in the ha-evcc), that there had been no other issues/errors with the request/response

How about checking whether the status code is 200?

@andig
Copy link
Member Author

andig commented Jul 11, 2025

Exactly that 👍🏻

@marq24
Copy link
Contributor

marq24 commented Jul 11, 2025

How about checking whether the status code is 200?

of course the ha-integration is checking for http status 200, before reading any json data... I personally prefer, when http status codes are not used to indicate application layer information - so http 200 must not mean, that the response itself have valid/consistent data... But since this is just my opinion, and since it's your project, I will adopt to this change.

@andig
Copy link
Member Author

andig commented Jul 11, 2025

I'm not saying that it necessarily does but at the same time I'm not aware of any best practice requiring wrapping json payloads in top level elements which is what we're changing here.

and since it's your project,

I disagree (and I personally don't like the wording). It is a community project and we're open to feedback! Adhering to best practices certainly is of high value to us.

@marq24
Copy link
Contributor

marq24 commented Jul 11, 2025

I disagree (and I personally don't like the wording). It is a community project and we're open to feedback! Adhering to best practices certainly is of high value to us.

I must assume, before starting with this breaking 'everything' change, you had internally (e.g. in slack) discussed the pro's & con's already. I highly appreciate the overall structure of this project and the clean code principles. So there is great experience & expertise in the core development group. Getting rid of an obsolete container object seams to be reasonable.

The only thing I wanted to remark was triggert by "why not (simply) check for http 200?" - From my point of view, http 200 should not be the indicator, that the response object is in the expected format or structure. So processing any API response with http status 200 must be done with care and without any additional assumptions.

In the HA integration, I have (mis)used the presence of the result container in any of the API responses, as validation: that the request was processed by an evcc-endpoint and "seams to be valid in it's internal structure" - at least it has not been generated by any infrastructure in between. For sure this approach was also far from being perfect, but IMHO it is quite a cheap' approach (CPU & data wise) and nobody really want to return to SOAP.

So when the result will not be present any longer, I have to rethink the current data-validation-procedure - which probably take less time, then writing this reply :-)

marq24 pushed a commit to marq24/ha-evcc that referenced this pull request Jul 11, 2025
- re-configuration instead of options
- prepare for "result" container being removed (evcc-io/evcc#22299)
marq24 pushed a commit to marq24/ha-evcc that referenced this pull request Jul 11, 2025
- re-configuration instead of options
- prepare for "result" container being removed (evcc-io/evcc#22299)
@marq24
Copy link
Contributor

marq24 commented Jul 11, 2025

@TheNinth7
Copy link

TheNinth7 commented Jul 12, 2025

An update for the Garmin app will be released in the next few days, adding support for both JSON formats - with and without the "result" wrapper. The app uses a jq filter to reduce memory usage, and the filter has been updated to handle both cases.

The code was tested with the old format, but I can only fully verify support for the new one once the update is live. Mock servers can't replicate how the jq filter is applied by the actual server.

Side note: AI isn’t much help with Garmin’s Monkey C or SDK, but it is well-versed in jq and was also helpful in this case. 😉

@TheNinth7
Copy link

@andig I also noticed the openHAB evcc binding isn’t showing up in the list. Maybe it needs an update too to handle the new JSON format?

@andig
Copy link
Member Author

andig commented Jul 12, 2025

Whom do we need to cc?

@TheNinth7
Copy link

Whom do we need to cc?

@florian-h05, would you be the right person to look into how this change affects the openHAB evcc binding? Or do you happen to know who maintains it currently?

@florian-h05
Copy link

florian-h05 commented Jul 12, 2025

Technically I am still the maintainer, but the last changes (including adjustments to API changes) were done by @marcelGoerentz & @MikeTheTux.
This change means that the DTO needs to be adjusted, should be relatively straightforward. If we want to keep backwards compatibility however this would be slightly more complicated.

@marcelGoerentz
Copy link
Contributor

marcelGoerentz commented Jul 12, 2025

Technically I am still the maintainer, but the last changes (including adjustments to API changes) were done by @marcelGoerentz & @MikeTheTux.
This change means that the DTO needs to be adjusted, should be relatively straightforward. If we want to keep backwards compatibility however this would be slightly more complicated.

I've reworked the whole binding for openHAB and made it modular. Backward compatibility should be no problem at all, since it will be just a few lines where it can check for whether the wrapper is present or not.

I did not raise a PR yet, since I need some other user to test it and finalize it.

@marcelGoerentz
Copy link
Contributor

@andig What will be the response when you set a value. For example the batteryboost for a loadpoint?
If you don't send back:

{
  result:"true"
}

@naltatis
Copy link
Member

naltatis commented Jul 12, 2025

@andig What will be the response when you set a value. For example the batteryboost for a loadpoint? If you don't send back:

{
  result:"true"
}

My expectation would be simply "true", which is valid JSON.

Update (tested):

before

{
  "result": true
}

after

true

@Maschga
Copy link
Contributor

Maschga commented Jul 12, 2025

by PR evcc-io/docs#842

@andig
Copy link
Member Author

andig commented Jul 13, 2025

Are there any objections merging this into the nightly once openhab is ready? @thecem I believe we can remove you from the todo list?

@thecem
Copy link
Contributor

thecem commented Jul 13, 2025

Are there any objections merging this into the nightly once openhab is ready? @thecem I believe we can remove you from the todo list?

Yes, this will not have an impact on Add-On for HA.

@naltatis
Copy link
Member

Are there any objections merging this into the nightly once openhab is ready?

Since this is a significant change which will also affect many custom/private evcc integrations I'd suggest not merging it yet. Lets first do a "regular" release.

@thecem
Copy link
Contributor

thecem commented Jul 13, 2025

Probably there should be some hint in the release notes for the next release that there will be some breaking changes:

Recommendations

  • Check Before Updating: Make sure you are using the latest version of the Home Assistant integration that supports the new response format. Review the release notes for your integration.
  • Update Custom Automations: If you use custom REST sensors or scripts, update them to access response.data instead of response.data.result.
  • Wait for Official Updates: The developers recommend waiting to update evcc until the relevant integrations (especially openHAB and Home Assistant) are ready for the new format.

@marcelGoerentz
Copy link
Contributor

I will raise the PR for the openHAB binding to night or in the next few days. So openHAB should be fine with the next API change. Maybe users need to download the binary files from my fork until the next official release of openHAB, but that should not prevent you from merging this PR.

@capi
Copy link

capi commented Jul 13, 2025

Hi, I'm currently also using the evcc API in my integration to wake up my Dacia Spring via ODB-II when it's in deep-sleep in my project https://github.com/capi/springwatch-elm327-evcc

Do I understand it correctly, that I will handle both old and new API version correctly with the following change? (Python)

    def load_state(self):
        url = f'{self.evcc_url}/api/state'
        response = requests.get(url)
        response.raise_for_status()
        data = response.json()

        # Breaking API change incoming: https://github.com/evcc-io/evcc/pull/22299
        # Handle both old format (with "result" wrapper) and new format (without wrapper)
        # This provides backward compatibility during the API transition
        if "result" in data:
            # Old format: {"result": {"loadpoints": [...], ...}}
            return data["result"]
        else:
            # New format: {"loadpoints": [...], ...}
            return data

@marq24
Copy link
Contributor

marq24 commented Jul 13, 2025

Do I understand it correctly, that I will handle both old and new API version correctly with the following change? (Python)

    def load_state(self):
        url = f'{self.evcc_url}/api/state'
        response = requests.get(url)
        response.raise_for_status()
        data = response.json()

        # Breaking API change incoming: https://github.com/evcc-io/evcc/pull/22299
        # Handle both old format (with "result" wrapper) and new format (without wrapper)
        # This provides backward compatibility during the API transition
        if "result" in data:
            # Old format: {"result": {"loadpoints": [...], ...}}
            return data["result"]
        else:
            # New format: {"loadpoints": [...], ...}
            return data

yes - this looks fine (and that's what I have also implemented... just with a additional check, if data is not None...

capi added a commit to capi/springwatch-elm327-evcc that referenced this pull request Jul 13, 2025
In evcc-io/evcc#22299, the API result will no
longer wrap the data in a "result" object.
This change can work with the old and the new API response format.

Unit tests have been auto-generated by Github Copilot.
marq24 pushed a commit to marq24/ha-evcc that referenced this pull request Jul 14, 2025
- prepare for "result" container being removed (evcc-io/evcc#22299) - fix
- initial handling of chargerSinglePhase, chargerFeatureIntegratedDevice loadpoint attributes
- do not add (vehicle) entities for loadpoints that are 'IntegratedDevice'
arteck added a commit to Newan/ioBroker.evcc that referenced this pull request Jul 16, 2025
* (arteck) simplify json response by removing result wrapper, see evcc-io/evcc#22299
@andig
Copy link
Member Author

andig commented Jul 17, 2025

Announcement is done via release notes and discussions: #22416.

I'd tentatively like to schedule this for 0.206.0.

@marq24
Copy link
Contributor

marq24 commented Jul 17, 2025

I'd tentatively like to schedule this for 0.206.0.

my experience with HA Integration users is, that they update Integrations not frequently - but the obvious question is, "how long you are willing to wait" with the rollout of this PR... In my opinion this change does not add any (awaited) functionality - therefor the release-pressure is not high (IMHO)

@andig
Copy link
Member Author

andig commented Jul 17, 2025

The pressure comes from the other release contents. But we'll need to merge this into the nightly before.

that they update Integrations not frequently

This will be an issue for any release, be it sooner or later?

@capi
Copy link

capi commented Jul 17, 2025

Maybe make it a "dedicated" release, where people can roll-back to the previous version if they cannot immediately update their integrations? I guess, a lot of people are on the "latest" tag when using Docker and will otherwise be quite surprised by the update and it would be beneficial, if they could rollback one version in order to update their home automation integrations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
infrastructure Basic functionality needs documentation Triggers issue creation in evcc-io/docs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy