Creating your own xml namespace - spring

I have followed the tutorial on https://spring.io/guides/gs/producing-web-service/ for creating an app which will receive SOAP requests and should return some SOAP response. However, the namespace in the tutorial is just an example. How can I create my own namespace (URI, prefix, content...)? I have been searching, but not successfully...Thanks in advance!

As I mentioned in the comment above, you should read this post to understand what an XML namespace is: What are XML namespaces for?.
The gist of it, in the context of your question, is that it provides some context about the elements in your XML. For example, if your service encounters a <table> element, how does the server know what kind of a <table> this is?
Is it this?
Is it this?
Or is it this?
Namespaces allow you to differentiate between them by adding a namespace:
<table xmlns="urn:tabular-data:tables">
<table xmlns="urn:chemistry:periodic-table">
<table xmlns="urn:products:furniture:kitchen-table">
You might also want to check this question out to see what I did in here, but in short, I just made those up. I invented them on the spot.
In your example, you can do the same.
The thing is that a SOAP message is an XML composed of different element. Some belong to SOAP itself, some belong to your application, some belong to other web service specifications, etc, and your service needs to make sense of them. That's why you use namespaces, so that you add meaning to the elements. For example, on that page you have this request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:gs="http://spring.io/guides/gs-producing-web-service">
<soapenv:Header/>
<soapenv:Body>
<gs:getCountryRequest>
<gs:name>Spain</gs:name>
</gs:getCountryRequest>
</soapenv:Body>
</soapenv:Envelope>
When you say it's an envelope, you don't mean any envelope, you mean a SOAP envelope. And you know it's a SOAP envelope because its namespace is http://schemas.xmlsoap.org/soap/envelope/. The SOAP payload itself has elements from the namespace http://spring.io/guides/gs-producing-web-service.
Both are invented, the only difference is that http://schemas.xmlsoap.org/soap/envelope/ after it was invented it was standardized in a document so that everyone knows what it means. You don't need to standardize yours (http://spring.io/guides/gs-producing-web-service isn't either), you just need to invent one that is unique and specific to your context.
People usually use domain namespaces that they own, maybe even throw some timestamp in there. So you can use for example http://jovana-vajagic.com/2021/03/20/example-service if you think that is unique to you. Or you can use urn:uuid:8f4ac50e-574b-4936-b49b-8b129bea945b if you want to (I got that random UUID from here).
So basically, you just invent one that is fairly unique, and you replace it in the code of that example you are following.
As for defining elements within that namespace, you will need an XML schema where you define your elements, sub-elements, attributes, their types, etc. Look in the tutorial you are following and you will see there is a section on XML schema:
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://spring.io/guides/gs-producing-web-service"
targetNamespace="http://spring.io/guides/gs-producing-web-service"
elementFormDefault="qualified">
...
You need to create something similar, using your namespace (like http://jovana-vajagic.com/2021/03/20/example-service or whatever you chose) and declare your elements in there.
You will have some reading to do :) Good Luck!

Related

Can not get number of xml nodes from document using spring integration

I am attempting to get the count of the //Root/Record elements using spring integrations int-xml:xpath-header-enricher. It comes back zero regardless of the document passed in.
You have to configure your XPath expression like this:
<int-xml:xpath-expression id="countExpression" expression="count(//ns:Ephemeris/ns:Record)"
ns-prefix="ns"
ns-uri="http://www.sandia.gov/pgmm/Ephemeris"/>
And have it as a reference from the <int-xml:header> instead.
The problem is that your root element in the XML comes with the xmlns="http://www.sandia.gov/pgmm/Ephemeris", so, there is no other way unless we honor namespaces in your source XML. For this purpose we introduce artificial prefix, even if your source XML does have then. We need that in XPath to properly distinguish elements based on some namespace.
I think default DocumentBuilderFactory just doesn't honor namespaces making your possible XPath expressions much horrible when it comes to several namespaces support.

Documenting fields in Django Rest Framework

We're providing a public API that we use internally but also provide to our SaaS users as a feature. I have a Model, a ModelSerializer and a ModelViewSet. Everything is functional but it's blurting out the Model help_text for the description in the API documentation.
While this works for some fields, we would like to be a lot more explicit for API users, providing examples, not just explanations of guidance.
I realise I can redefine each field in a Serializer (with the same name, then just add a new help_text argument, but this is pretty boring work.
Can I provide (eg) a dictionary of field names and their text?
If not, how can I intercede in the documentation process to make something like that work?
Also, related, is there a way to provide a full example for each Viewset endpoint? Eg showing what is submitted and returned, like a lot of popular APIs do (Stripe as an example). Or am I asking too much from DRF's documentation generation? Should I handle this all externally?
To override help_text values coming from the models, you'll need to use your own schema generator subclass and override get_path_fields. There you'd be able to prioritize a mapping on the viewset (as you envision) over the model fields help_text values.
On adjusting the example generation - you could define a JSON language which just deals with raw JSON and illustrate the request side of things pretty easily, however, illustrating responses is difficult without really getting deep into the plumbing, as the default schema generated does not contain response structure data.

ActionMethodSelectorAttribute equivalent in ASP.NET Web API?

Is there a Web API equivalent to the MVC ActionMethodSelectorAttribute?
My specific purpose is this: I have, for example, a ResourceController and when I POST to the controller, I'd like to be able to receive a single resource (Resource) or a list (IEnumerable<Resource>).
I was hoping creating two methods with different parameters would cause the deserialization process to do some evaluation but this doesn't seem to be the case (and frankly, I don't think it's efficiently realistic with the combination of content negotiation and the fact that many data formats, like JSON, make it difficult to infer the data type). So I originally had:
public HttpResponseMessage Post(Resource resource) {...}
public HttpResponseMessage Post(IEnumerable<Resource> resources) {...}
...but this gets the "multiple actions" error. So I investigated how to annotate my methods and came across ActionMethodSelectorAttribute but also discovered this is only for MVC routing and not Web API.
So... without requiring a different path for POSTing multiple resources vs. one (which isn't the end of the world), what would I do to differentiate?
My thoughts along the ActionMethodSelectorAttribute were to require a query parameter specifying multiple, which I suppose is no different than a different path. So, I think I just eliminated my current need to do this, but I would still like to know if there is an equivalent ActionMethodSelectorAttribute for Web API :)
I haven't seen a replacement for that method (there is an IActionMethodSelector interface but it is internal to the DLL). One option (although it seems like it might be overdoing it) is to overload the IHttpActionSelector implementation that is used.
But changing gears slightly, why not always expect an IEnumerable<Resource>? My first guess is that the collection method (that takes IEnumerable<Resource>) would simply loop and call the single value (just Resource) function?

Tx NameSpace in spring?

I have seen everywhere using tx namespace in springconfig.xml.Can we use tx1 instead of tx? i mean is it kind of hardcoded when xml is processed during parsing?
Since Spring configuration files are just XML files and the parsing of them happens at the infoset level (where it should happen, of course) you can indeed change the prefix to anything you want with an appropriate xmlns:… declaration. What you can't change is the namespace URI that the arbitrary prefix is bound to; that must be correct.
But I suggest using tx if at all possible: it makes it easier for other people (or yourself in a few months time) to come to your config file and read it quickly. No point in making things deliberately obscure after all, since Spring is complex enough without.
If you want to use a xml namespace prefix, you have to define it. The first element of an spring appliction context file has often this attribute:
xmlns:tx="http://www.springframework.org/schema/tx"
This means that all elements having the tx prefix belong to the http://www.springframework.org/schema/tx namespace. If you want to use another prefix you have to change the above attribute:
xmlns:tx1="http://www.springframework.org/schema/tx"
Now every element starting with tx1: belongs to the mentioned namespace.
This is not specific to spring but belongs to the XML schema definition language (xsd).

xsd - validating values from external dictionary file

I would like to define a schema for a document like:
...
<car>
<make>ford</make>
<model>mondeo</model>
</car>
...
the problem is that I would like to constraint possible values (so ford/mondeo or audi/a4 would be valid values for make/model, but audi/mondeo would not) from external data dictionary. In case when new car models needs to be added only external data file would change, but xsd schema would remain the same.
Is this possible at all? I have looked at key/keyref constraint, I see I can use them within a single document, but this is not I'm looking for. I don't want to repeat full data dictionary with every document instance, I would prefer to have the data file rather constitute part of the schema.
That is not possible in XML Schema 1.0.
XML Schema 1.1 will add some support that will allow expressing this kind of constraints (although AFAIK not in external files) - but that is not yet a W3C recommendation.
It is possible to implement this now with Schematron, eventually embedded in XML Schema.
However, there was already work in this area with usable results. See OASIS Code Lists
http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=codelist
More details can be found here:
http://www.genericode.org/
This is used in the OASIS Universal Business Language (UBL)
http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=ubl
Best Regards,
George

Resources