3

I have an API I have designed which can return data in 2 different units. To explain this I am tending to use the example of a measurement, in particular temperature. However my use case is slightly more complex, representing a tree of values with percentage values on each level, whether showing this in relation to the parent, or the top of the tree.

I am looking how I would accept a value and a unit for that data. For example say my API returns a bunch of temperatures:

GET:{
  temperature_c: 20,
  temperature_f: 68
}

Now say I want to set a temperature, I would only expect to receive one temperature as I don't want to force the consumer to calculate a value they don't know/care about.

But is there any recommended RESTful way to do this? I have thought of using a query parameter:

PUT?unit=c:{
  temperature: 20
}

Or to add a unit field into the body:

PUT:{
  temperature: 20,
  unit: c
}

Or, what I feel is worse, forcing a consumer to one of the types:

PUT:{
  temperature_c: 20
}

Is there any standard way of approaching this problem? Or any significant drawbacks? Or perhaps there is another method I am missing?

Edit: For information of my intended usecase, I plan to represent a tree structure which exposes weights in two forms 'to top' and 'to parent'. To Top being the overall weight of the node, as a % of the entire tree. To Parent being the weight of the node, as a % compared to it's immediate parent. As an example, imagine this tree structure and weights:

-- Nodes            To Top   To Parent
Root node           100      100
    Node 1.1        80       80
        Node 1.1.1  60       75
        Node 1.1.2  20       25
    Node 1.2        20       20
        Node 1.2.1  10       50
        Node 1.2.2  10       50

I can easily convert between each, however if a consumer manipulated To Parent for example, I feel they shouldn't also have to work out the To Top weights before doing a PUT/POST.

  • 1
    consistency is always nice imo. If I get a temperature_c, I'd expect to deal with temperature_c going forward rather than having to remember how to map it. – bitsoflogic Jun 22 '18 at 14:16
  • why you care to provide two representations of the same data with the GET and not an option to select the format as you're facing with the PUT? Does the client need all the representations at once? – Lord of the Goo Jun 22 '18 at 21:34
  • Why is "forcing a consumer to [use?] one of the types" worse? They're already using one of the types, and they should know what that type's name is. – jwodder Jun 23 '18 at 01:01
  • @jwodder This is the worst only if we are under a generic endpoint which retrieves both figures (C and F), if I had 2 endpoints, one for Celsius, one for Fahrenheit I would definitely be fine just accepting temperature and knowing from the endpoint it would be Celsius. However if I provided both C and F, I would not want the PUT/POST only to accept C as it forces more work to the consumer. I would like to provide both figure types, and support receiving both figure types, just how to do that in a consistent way is my issue. – David Lynn Jun 27 '18 at 12:11
  • @LordoftheGoo I could see the client needing both figures at once (currently our consumer is playing with both figures) however I am flexible with the GET as well as the POST, it sounds as if 2 endpoints, Celsius/Fahrenheit may be the most applicable for this issue. Perhaps a generic GET only which provides both figures. – David Lynn Jun 27 '18 at 12:15
  • @bitsoflogic Thanks, I agree, that rules out the second option somewhat. I want to make it very clear that the values received and put from this endpoint are in a certain unit. – David Lynn Jun 27 '18 at 12:18

1 Answers1

4

Allowing different representations for the same data is fairly common - for example, many web services provide both XML and JSON output chosen by the client.

Your options are all fine (even forcing the representation, even though it might be inconvenient for some clients as long as you're consistent about it, it's something they'll be able to adapt to). Other than the options you've already mentioned you could also have slightly different URLs myservice/temperature/[celsius,fahrenheit].

That being said, you indicate that your usecase is "more complex" - you don't say what your exact problem is so it's hard to tell if any of these would be more or less appropriate for your particular use case.

Jerry Coffin
  • 44,495
Cubic
  • 301
  • 2
  • 10
  • Should we really allow different representation between GET and POST on the same url? At least using different urls would be more logical. – pdem Jun 25 '18 at 11:34
  • @pdem It's the same resource, regardless of representation. You can have two different URLs to the same resource, but you don't have to. – Cubic Jun 25 '18 at 12:29
  • Thanks @Cubic, I have added a description of my intended usecase and am most tempted down the road of different URLs for PUT/POST. That allows me to keep consumers free from a type they are not interested in. Given the example, do you think this is appropriate? I am also tempted to provide a 'all' endpoint like so: myservice/temperature/ Provides/requires both figures for Get/Post myservice/temperature/[celsius,fahrenheit] Provides/requires only the requested figure. – David Lynn Jun 27 '18 at 11:57
  • @Cubic using a URI segment to customize the format isn't a good choise: it violates many well accepted practice in REST API design. Format options should be convey by other means: querystring, Accept header… – Lord of the Goo Jun 30 '18 at 21:50