Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Specfy additional field in operationbinding?

    hi! In a DataSource, say i want to have an additional field only in add responses. From what i've read, i do that by declaring an operationbinding with an "outputs" field in the ds.xml like this:

    Code:
    <operationBinding operationType="add">
                <serverMethod>dsAdd</serverMethod>
                <outputs>extraField</outputs>
            </operationBinding>
    Now, as mentioned i want all the 'regular' fields in the xml, plus one additional. I am wondering if there is any way/syntax for that? Something like "*, myextrafield". Duplicating every field in the datasource again is pretty error prone and verbose if you see what i mean.

    Cheers

    #2
    Hi mathias,

    I'm pretty sure you'll have to define the field in the fieldlist of that .ds.xml, meaning you can't return data for a non-existing field.

    Once the field is defined I assume you'll have to give a cacheSyncOperation to your add-operationBinding with the full outputs list or alternatively add customSQL=true to your additional field.
    I also struggled with the super long output lists here and suggested "doesNotOutput", which might not be needed after all with customSQL=true.

    Best regards
    Blama

    Comment


      #3
      You have to declare the field in your <fields>. Then, presumably your code only returns / populates this field in add responses? If so, you don't have to do anything further.

      Note: Blama's response is based on what you might need to do if you had a heavily customized SQL query or queries for an "add" operation. Doesn't apply to you, since based on previous responses, you seem to use Java beans as your responses.

      Comment


        #4
        Hi thanks to both of you for responding quickly! I don't think you're correct though.

        This is the iso docs on the outputs field in operationbinding:
        Specifies, for this operationBinding only, the list of field names that should be returned to the client. Typically this will be a subset of the DataSource.fields, but note that this is not a requirement; outputs can include fields that are not defined in the DataSource's field list.
        I also tried it myself just now - i duplicated every field name from my datasource xml <fields> comma separated into the option "outputs" field, as well as my extra field, and it works. When i add a record, everything is returned, including the additional field.

        However, as i mentioned, it's a pretty flaky approach, hence my original question. Perhaps i should include it in fields like you say, i just don't like an empty field being sent across the wire 99% of the time... in json/jackson you can annotate a field with for example @JsonInclude(JsonInclude.Include.NON_EMPTY), so that it's only sent if it is set. Would have been great if i could have done something similar here.
        Last edited by mathias; 9 Nov 2022, 10:50.

        Comment


          #5
          So again, if you simply do not specify outputs, everything is sent. So for correct function, you simply do nothing.

          As far as avoiding sending data for field which will not be used, unless this field is either very, very large or very expensive for your custom code to retrieve, removing it is unlikely to have any measurable impact on performance. However if you are excited to perform this optimization nevertheless, just put outputs on the fetch operation, omitting this field and any other fields that aren't needed for fetches. You can also do this programmatically instead of in XML, if the field list is the same across multiple operations and you don't want to repeat it.

          As far as optimization overall, we would highly recommend reading our recent article on web application optimization. Based on previous discussions on this forums, it seems likely that your current application is missing out on improvements in the realm of 2-20x, whereas you are currently looking at an improvement that we would guess is around 0.3%, if measurable at all.




          Comment


            #6
            Performance is not the main reason. It's more about server logs, code understandability, DAO/Bean fields, network tracing etc. I am usually trying to keep things clean if you see what i mean. I probably am too pedantic, but i'm too old to change. Back in the c64 days, this kind of stuff used to be important, heh.

            Having said that, i did end up putting it in fields, since duplicating all names in the options field is even messier :)

            Comment


              #7
              Since you're talking about things being "messier" than one another, sorry, but we need to reiterate:

              1. correct function is achieved by simply doing nothing. No duplication of any kind.

              2. an optimization (which is probably not worth pursuing) is possible by listing out the set of fields that should be returned by the fetch operation, once. No duplication.

              Comment


                #8
                I'm not following, but whatever. (That's not i was after. I wanted one additional field only being sent after an add operation. The only way to do that, from what i have understood, is to use the options field in a custom add)

                Comment


                  #9
                  It's not options, it's operationBinding.outputs. As we explained above, there's little point in limiting the field to just the "add" operation, as it would not change the function of other operations and is not a meaningful optimizations.

                  But if you wanted to limit it anyway, as also explained above, it would take just one, non-redundant outputs declaration to remove it from the fetch operation (the only meaningful optimization), and, if for some reason you wanted to remove it from all operations, the easiest way is programmatically: in pseudocode, it's just something like :

                  Code:
                      dsResponse.setOutputs(dataSource.getFieldList().remove("theField"))
                  With Server Scripting, you could embed this right in your .ds.xml.

                  Comment


                    #10
                    OK, it seems we don't agree on how it works. I will reiterate one last time since what i have written is corrent:

                    My goal as i initially stated it in my first post, was to include an additional field only in the 'add' operation and not as part of the datasource itself.
                    I found out that i can achieve that using the "outputs" field if i want, but it is messy since i have to reiterate all field names again, and add my custom field. This is error prone.

                    Consider the following (simplified) datasource.
                    Code:
                    <?xml version="1.0" encoding="UTF-8"?>
                    <DataSource ID="user" xmlns:fmt="http://www.apache.org/internal/xmlbeans/wsdlsubst" dropExtraFields="false">
                        <fields>
                            <field name="id" type="long" hidden="true" primaryKey="true"/>
                            <field name="idNumber" type="text" length="15" required="false"/>
                            <field name="name1" type="text" length="32" required="true"/>
                            <field name="name2" type="text" length="32" required="false">
                            </field>
                            ......
                        </fields>
                        <operationBindings>
                            <operationBinding operationType="add">
                                <serverMethod>dsAdd</serverMethod>
                                <outputs>id, idNumber, name1, name2, pwd</outputs>
                            </operationBinding>
                            ......
                        </operationBindings>
                        <serverObject lookupStyle="spring" bean="userDS">
                        </serverObject>
                    
                    </DataSource>
                    By using this configuration, the "pwd" field is not declared in the fields section, it is not sent across the wire or logged anywhere but in the dsresponse of the "add" operation, and no need for java code.

                    I have manually tested this as i mentioned above.

                    So, it simply isn't correct that there "is no point" using the outputs field and that it "wont change the function of other operations".
                    It *is* a way to "limit it anyway", and it achieves the same, suggested, optimization as using java code to manually remove the field for all the other operations in Java Code (or server scripting apparently).
                    The advantage compared to java code is also that it is contained in the datasource configuration file.

                    This also tracks with your documentation.

                    Thanks though for the scripting tip, had not read up on that.
                    Last edited by mathias; 11 Nov 2022, 00:48.

                    Comment


                      #11
                      Hi mathias,

                      this is why I suggested customSQL=true.
                      This way you don't have to use outputs, which means you don't have to remember to add a new field added later to outputs as well.
                      Basically customSQL defaults to a never-used field that you can enable for certain use cases (=operationBindings).

                      From the docs (I think the first one is your use case):
                      Use customSQL in situations like:
                      • there are multiple variations of the "fetch" operation with different operationIds, and the field is only used in some of them; in that case, consider using OperationBinding.customFields to selectively re-introduce SQL generation for the field only in operations where it's used.
                      • the field represents hidden criteria on a field in another table where the field is never shown to the user
                      • the field is a write-only value only saved in some operations
                      • more than one data access strategy is in use (eg direct SQL for fetch and bean-based persistence accessed via DMI for saves) and certain fields are not available in SQL
                      Best regards
                      Blama

                      Comment


                        #12
                        Mathias, we are saying the same thing but using the word "function" differently.

                        We are saying that if you do the simplest possible thing - just add the field definition, and nothing else - then from the point of view of the function of the application, that is, how it behaves as seen by an end user, you are already done - no further effort is required. Here we are using the word function in a way in which it is commonly used, as in, functional design, for example.

                        But then, it seems like for reasons other than function, and other than optimization, you just really don't want that extra field (logging, as you said). That's very easy to achieve, roughly:

                        Code:
                        if (operationType != "add") dsResponse.setOutputs(dataSource.getFieldNames().remove("theField"));
                        Note that we had to follow this discussion all the way to this point, even though it that's a poor use of time, because you referred to various solutions being "messier" than one another. That a pejorative word being used publicly, and it has real impact, since someone coming upon this thread would likely come away with the impression that this use case can only be handled in one or another "messy" way.

                        Clearly this is not a use case that has a messy solution.

                        If you could please be a bit more careful about negative descriptions, that would be great, and would save us all time.

                        Blama: Mathias is not using our SQL engine, so customSQL is not an applicable setting.

                        Comment


                          #13
                          Blama sure but my datasources are spring, we reuse them for other interfaces like push, sms, rest etc.

                          @isomorpic I have read through this thread and i'm at a loss as to what you mean with "negative description". I spent a lot of time giving you a detailed example to be clear what my end goal has been. I suggest we end this thread. All the best
                          Last edited by mathias; 14 Nov 2022, 00:17.

                          Comment

                          Working...
                          X