I am designing a web service accepting POST requests with JSON in the message body. I want the requestor to be able to specify multiple values for a parameter, but also single values.
So, for simple cases I support JSON like:
{
"name" : "value"
}
And, in more complex cases, I also support JSON like:
{
"name" : [
"value one",
"value two",
"value three"
]
}
My question is: is this an abnormal interface for a Web Service? Am I overcomplicating things here?
The alternative would be, as I want to support arrays of values, to require arrays of values, even for the simple case:
{
"name" : [
"value"
]
}
I don't like this but want to get the community's input before making a decision.
EDIT:
I removed the word REST from the conversation as that factor isn't really important here.
It is typical of a web service to accept an array of values for a POST request. However, the number of elements may be zero or many. Keeping it as an array of values, even if only one value is going in, is going to keep things simple and consistent.
If a user of the web service needs to submit a single element for creation or modification (upsert), then perhaps a PUT request would be more appropriate.
I will prefer a single structure for both cases and then there will be only one processing logic to code and no need for special case to decide on.
Also this is not much of REST related. It is more of on trading off on the the processing or handling of the data v.s. whatever reasons that drive you to think of splitting the data into two forms in the first place.
Hope this help.
REST is about resources and their representations. So ask yourself:
What resource does the JSON represent?
Can you answer this question?
From the JSON in your question I would say, the resource is an object that has names
. It is not an object that has one name.
So I recommend to use your second approach.
Related
I am currently looking to build out an event driven EventBridge event module (as opposed to a scheduled one, for example) for usage in our IaaC portfolio. The example code below shows how the normal event JSON pattern would look. I can obviously add a normal single variable for the "detail-type" and the "source", but can someone advise on a way to create some kind of single mapped variable that I could pass one or more parameters for the "detail" map?
event_pattern = <<PATTERN
{
"detail-type": ["Glue Job State Change"],
"source": ["aws.glue"],
"detail": {
"jobName": ["${var.env}_${var.department}_gluejob_${var.pipeline}_publish-small", "${var.env}_${var.department}_gluejob_${var.pipeline}_catalog", "${var.env}_${var.department}_gluejob_${var.pipeline}_publish-large", "${var.env}_${var.department}_gluejob_${var.pipeline}_notify"],
"state": ["FAILED"]
}
}
The need for this is that across a number of different services we may need any number of key and value parameters in "details" so some way to pass in a map which can have any number of key value pairs would be ideal. Now if this wasn't json I could use a dynamic value in TF but I am unsure what to do here with it being an inline JSON pattern.
I should also mention before someone suggests it, that I have currently just done the work around of having the event pattern passed as variable and using data and a template json.tpl file that can pass the pattern for each resource in individually for each usage of the module, but would like to know if anyone can advise on the solution I was hoping was possible above?
Any advice would be greatly appreciated!
I am parsing an XML document to JSON, and eventhough I have the type array declared in the json schema, if there is just one element in the array it gets transformed into an objet like this.
"ListOfCodes":{"Codes":{{"Code":"111"}}}
but I need this:
"ListOfCodes":{"Codes":[{"Code":"111"}]}
I have several arrays in the document and I only get the sqare brackets when there is a multiple array.
and adding the properties manually is not an option.
Anyone know what can i modify to fix this in the logic app?
Unfortunately, there isn't a good solution for us to implement this requirement in logic app. Here is another post which is similar to your problem. To implement the requirement, we can just:
1. Use the "Compose" action to generate the object by hand (manually put all the properties and arrays where they need, potentially using the #array() action.
2. Call an Azure Function or some external code that can more specifically craft a valid JSON.
I also try to test it in some other way, such as use json:Array="true" and use <?xml-multiple?> but they all fail in logic app. So I think the only above two solutions(mentioned in that post) can be used. Neither approach is good, though.
I were working on my app today and when my friend looked on my code he told me that before I'm making an HTTP request to update objects I should remove the properties that are not used in my server and I didn't understand why.
I didn't find any best practice or any explanation on the web why it is better to clean my objects before sending them to my server...
Let's say I have a dictionary with 100 keys & values with the same properties (but different values) like this one:
{
'11':{'id':11, 'name':'test1', 'station':2, 'price': 2, 'people':6, 'show':true, 'light': true},
'12':{'id':12, 'name':'test2', 'station':4, 'price': 2, 'people: 1, 'show': true, 'light': false},
....
}
The only thing I need to change is the station of each pair. The new station number is set on my client and sent to my server to make an update in my DB for each pair...
Should I iterate over the dictionary and clean every object before making an HTTP request to my server as my friend said?
I can not add a comment because of my reputation, so I'll put as an answer
Not necessarily, it depends a lot on how your server's API works, if it expects an entire object, it's no use cleaning, now if you have the option to send only the modified element, you do not have to send the entire object.
The HTTP request will work in the same way with a single piece or with an integer object, but you can shorten the data traffic in kbps by sending less, only the Required, like as the changed values
Summary, it depends a lot on your approach, working single values and not whole objects you can do more generic functions and improve their entire scope.
Check: THIS It's similar to your question.
EDIT:
Maybe the cleanup he's referring to, is the question of clearing the code and sending only the necessary, so I understood the scope of the question
Remember that the less you pass, the more intact the original object will be (on the server).
It is a good practice to create generic (modulable) functions that only work with the necessary changes.
Couple reasons that come to mind:
plan for the unknown: today, your server doesn't care about the people attribute. But imagine you add something server side and a people attribute appears and is a string. Now all your clients fail, because they try to push numbers to a string
save the world: data is energy, and you're wasting it by sending more data that your server can handle, even if it's just a little
save your own energy: sending more attributes is likely to mean more work (to write the code and/or test it)
I'm developing a REST API based on the HAL specification. The API is being developed in PHP with Symfony and the client is being build in angularjs. The API must return some lists and they are going to be shown using ngtables library, and filtering options will be needed, ideally in the format that ngtables uses, like in this sample.
{ "name": "M", "age": "4" }
(Of course future clients may be use the same options.)
My frontend-workmate is suggesting me to send the json encoded directly as a parameter in the url, like this:
?filter=%7B%20%22name%22%3A%20%22M%22%2C%20%22age%22%3A%20%224%22%20%7D%20
I'm not very sure about that though.
I've been reading how to send arrays through the URL with a parameter like param[]=foo¶m[]=bar but that does implies have one key for multiple values. In my case I need to be able to send different key-values for the arrays like a Json object does.
I'm wondering how should be the Request URL from the client to be able to include all the filter options inside one parameteror and if there is any standard way to do that.
EDITED: After #Ross_Turner I want to clarify that my intention of passing a key-value array inside a parameter is because we'll have another type of parameter. For example:
?filter=<my key-value array>&page=1&limit=50&anotherParam=whatever
Even we would like to use another parameter containing another key-value array like this:
?filter=<my key-value array>&sorting=<another key-value array>&page=1&limit=50
Where filter and sorting can have the same keys.
Currently there is no standard way to send queries in GET requests. So you have 2 options: you use your custom query language (like you already tried) or you choose a standard query language. Either way it is hard to make it RESTful, because you have to create a link, which contains a recipe how to generate such an URI. You can probably use URI templates, but sometimes they are not general enough...
#Ross Turner:
I think you misunderstood, I was talking about not having a standard. Ofc. there are non standard query string based solutions, for example RQL. Or you can send a standard SPARQL query in a single param, but there is no standard way to describe such a link, and without link descriptions you cannot generate the query in a REST client, so it won't be loosely coupled and so it will violate the uniform interface constraint.
I disagree with #inf3ero's answer - surely there is a very well defined way to send a query as part of a GET request - query parameters. If you want different key and value combinations this is the principal of the keys and values of query parameters, so in your example you should probably use ?name=M&age=4 and parse each of these on your server. It should be simple enough to convert
{ "name": "M", "age": "4" }
into this by iterating over the keys in the JSON object. I'm not sure why you would want to combine these into a single parameter if you are attempting to implement a RESTful API following the HAL specification.
I'm having trouble finding an elegant solution to Enums and especially searching in Enums with AngularJS.
Let me describe a situation and how I handled it: Say I have an object called Event
This event has 2 properties : Severity and Status. Both of which are Enums, defined by ID (1, 2,3) and Title (for Severity : "Light", "Normal", "Important" and for Status : "Open", "Closed", "Pending Approval")
The Event objects that come from the Service have the ID's of the Enums, and when I want to display the object I bind with {{ severityIdToTitle(Event.Severity) }}
SeverityIdtoTitle is a method on my controller which calls a method on my service which returns the value of the Enum based on the id recieved
The problem arises when I want the user to be able to search the object through text, the AngularJS filter doesn't know the actual "string" value of the Enum, and so I reach my problem.
I know many workarounds around this, and have a few options, but I wonder what would be anelegant and clean solution to this? Did what I do complicate things and there's a better way?
Thanks guys!
Interesting question. I would create a custom filter instead of using the severityIdToTitle function. Filters are designed for formatting data to present to the user, so converting an id to a string is a good use case for one. The filter should depend on a service that knows the two-way mapping between the enum identifiers and their values. As for how to do that mapping, that is a general JavaScript question. There is one good thread about this here.