Rest API JSON Payload

Python, PHP, JavaScript, and even Java do it quite easily. But what rossko57 is referring to is how OH is architected and implemented. I tend to agree with him that it feels a bit odd to accept JSON into a plain old String Item. And since OH doesn’t have a JSON type Item, a plain old String Item is all we got.

But I also see Michael’s point because that means that the integration he is after isn’t possible.

So as far as I can see, the solution would be either:

  1. update the core so the REST API accepts all of the text types (text/xml, mime types, etc.)
  2. create a binding

Sounds like something for the OH3 roadmap :wink:

If the maintainers think it’s something appropriate to do. Just because something can be done doesn’t mean it should be done.

And, I suspect, unless it is listed ad a GitHub issue it would not even be considered.

I’m not sure I understand this concern. The magic of JSON is that it is a human readable String that can also be interpreted by computers. I think the situation would be different were this some binary format that could be corrupted by interpreting it as text. In that case I would agree with blocking it.

If it is improper to store JSON in a String, then is the transform function provided by openhab (which can take in a string and interpret it as JSON) also improper?

Should I open up an issue on github then? (Sorry, I’m very new to this community.) @rlkoshak 's proposal of accepting all text mime types would definitely solve my use case.

I believe this is the proper place.

Not at all. My concern is not about shovelling JSON content around in strings, of course that happens in just about any system, whether for convenience or necessity.

It’s about sending an http message that is marked as JSON to a well-defined service, and expecting that service to mishandle the JSON as though it were marked as text.

There’s no imperative for doing that, and it would be reasonable to resist it on the basis that it would adversely impact future development of the REST API. it’s not far-fetched to suppose some future enhancement that does use JSON properly - say, updating both state and tags, or updating multiple Items.

The REST API is quite specific to openHAB. While it is a tool for users, this use case here feels like it is being pressed into service to suit some more general requirement.

What is ideally needed for this job is an “HTTP Server” binding that could service unsolicited HTTP payloads, be they JSON or XML or what, and the user can (as with other bindings) use transformation techniques to pre-process, allot the data to several Items, and/or screen out rubbish, as they wish.
It would be generally useful, I think.

The closest existing thing is the TCP listening binding, which could be used here, but would require a fair amount of building onto I think.

2 Likes

The REST API is quite common and not specific to openHAB.

https://restfulapi.net/

JSON is extremely common when using REST APIs. If openHAB uses strings, that is indeed quite specific to openHAB.

You misunderstand the usage of the term here. English is a language. So is German. Therefore, all English speakers understand German? So it goes with API, and the subset of API called REST API. Sending a bundle of http to a Google Maps API with a bunch of data about Things and Items (i.e. OH format) isn’t going to do much.

The specific problem here is sending a message via REST API that says “set Item X to content zzzzzz”.
That goes wrong if you send “abcd” to a Number type Item, understandably.
But works if you send “3.14” (which is text, a string)

It’s fine to send some text “{ value: pair }” to a String Item.
But - gasp - that’s JSON!
No it isn’t, it’s a string that you can choose to interpret as JSON later if you wish.

The trouble here is with the HTTP that wraps around our actual message, which carries additional information about the type of content.
Every real OH REST API message expects http content type ‘text’
Even when the content is “3.14” destined for a Number Item.
The proposal is for http content ‘json’, which is not just text, it has key-value pairs, structure, hierarchy, etc. Which bit of that should we select as the OH payload?
What the OP wanted was for the REST API to break the http rules - “I know I said it was JSON, but please ignore that and treat it as though it was a long single string of text instead”
That’s not altogether unreasonable, but is a band-aid, a bodge.

1 Like

Looking ayt many configurations here, you would think so :smiley:
The API is specific but the REST API, especially using JSON is pretty much a standard now.

The OP does not want to use JSON, he wants to ignore JSON (until later)

All German speakers understand English of course :wink:

True but as a non-German speaker I get lost in many of the configurations here due to language barriers.

I worked for a Swedish company for a while ane all Swedes understand English. I got working with come Swedish C code (variable names made sense if you knew Swedish). Some alerts were Swedish only but I had people who could translate for me when I could not figure out the logic.

Indeed, REST is not specific to openHAB. It is a way to define an API. openHAB has implemented an API using this technique. But openHAB’s implementation is necessarily different from InfluxDB’s REST API or Roku’s REST API or Google Map’s REST API because it’s openHAB’s API. Every service that provides a REST API provides a unique implementation because an API defines how to interact with a specific service. There is not one REST API that everyone uses. There are an infinity of APIs that are implemented using the REST technique.

So rossko57 is right, the fact that openHAB doesn’t accept text/json to update or command Items is a choice of the openHAB developers. Not accepting text/json at that end point doesn’t mean openHAB isn’t using REST. Just because JSON and REST are very common doesn’t mean it makes sense for openHAB to accept JSON at that specific REST API endpoint for openHAB’s REST API. openHAB gets to define it’s own API in any way that it wishes.

I’m not arguing against modifying the REST API to accept text/json, though I tend to agree with rossko57 that it feels a little off. Typically it’s the job of the client (i.e. the thing making the REST API call) to conform to the API as defined by the service (i.e. openHAB), not the other way around.

So in my original example, my external provider has an api that I can periodically query. However the limits imposed by them mean that this is clunky, data has to be split up and the load on the system is quite big.

However they also have webhooks available, but they will only send json content. Using openhabCloud I could get the binding to set up the webhooks, but the problem is openhabs api cannot accept the json.

Thanks for the additional explanation! I guess I had been thinking about this as “just another binding” that wasn’t flexible enough to accomplish what I want, rather than as “The Official REST API for openhab”. I can see the argument that validation is desirable here, for example, if someday there is a JSON datatype and you want to only accept text/json when writing to such an Item.

I’ve gone ahead and accomplished what I needed with python/flask. It is another piece to manage, but it works.

Do we think its useful to open a github issue to be more flexible here? There seem to be several users asking for it, and IMO this behavior would be consistent with other parts of openhab. At least in rules, the system seems to be fairly liberal when coercing types (though I will admit, I’ve only been a user for < 1 month). Or is the consensus that this will be rejected and I should just move along?

I think you need to construct a good use case.
“I want to force arbitrary openHAB objects that expect text updates to accept JSON content, but to hack the format and not treat it as JSON but as a string instead, because …”
A better form of words would be wise, but the “because” part is important. This is a core part of openHAB intended for UI control, and changes won’t be made lightly.
Won’t be my decision, it’s just advice.

It’s not clear to me if a “proper” JSON REST API point would do what you want e.g. send JSON like
{ “Itemname”=“myItem” ; “state”=“ON” }

I’m not clear what security risks may arise; nothing extra, I guess.

It still strikes me that what is actually needed is a general “HTTP/HTTPS server (listener) binding” that would allow use of all the usual validation and transformation tools, choice of multiple channels to Items of varied type etc., and potentially offer some security validation (e.g. passwording)

As a hack, one can build their own using the conf/html config files. I do something similar to this to handle an OAuth2 callback in OAuth2 using just OH Rules and myopenhab.org. I’m not sure how easy or whether it’s possible to accept POST/PUT with a body in that way, but based on my experience most users are limited by their service only supporting GET webhooks.

Thanks for this link @rlkoshak, @rossko57 looks like I can use this hack for what I want to do :+1:

Good Day Guys
Just a quick question regarding the REST API, Is there any way to pass an event origin parameter to rest API and get it back from the event streaming API. What I want to do is differentiate the events coming from openhab and connected devices vs events coming back form the updates I sent from REST to avoid loops.
Cheers
Roshan

Short answer is no. If you are using Rules see Design Pattern: Manual Trigger Detection for a way to do this.