HL7 FHIR - How to modify the FHIR Schema and Run in local server - hapi-fhir

I'm trying to extend and override the FHIR schema and run it on the local server.
Could you please suggest me is there any way to customize the FHIR schema and run in local

Obviously if you want to just download the FHIR schemas, you're free to edit them to your heart's content and, but if your instances aren't valid against the un-edited schemas, then your systems will not be FHIR-conformant and you won't interoperate with systems or tools that depend on FHIR conformance (which is most of them).
Also, be aware that the schemas only reflect a small portion of the rules for conformance. XML schemas don't check slicing, vocabulary bindings, invariants or logs of other rules that must also be met. Most systems using FHIR don't use schema validation at all, or use it only as an initial "quick check" and will still conduct more thorough code-based validation against he rules in the FHIR spec.
There should never be a situation where you need to modify the FHIR schemas. The expectation in FHIR is that the 'extension' element will be used to convey additional data elements if any are required. If you need to represent a concept that FHIR doesn't have a resource for at all, then you can use 'basic'. In some cases (if the element doesn't have a required vocabulary binding) you may be able to send an extension such as 'data-absent-reason' in place of sending an actual value. The only situation where there's no mechanism to avoid populating an element and sending it as FHIR requires is if there's a mandatory coded element with a required binding. Those are both rare and generally easy to satisfy, though you may need to map your internal codes to FHIR to populate the element.
Rather than trying to modify the schema, you might be better served by asking the community (e.g. http://chat.fhir.org) how to meet your needs within the FHIR specification as it stands.

Related

Sub-resource creation url

Lets assume we have some main-resource and a related sub-resource with 1-n relation;
User of the API can:
list main-resources so GET /main-resources endpoint.
list sub-resources so GET /sub-resources endpoint.
list sub-resources of a main-resource so one or both of;
GET /main-resources/{main-id}/sub-resources
GET /sub-resouces?main={main-id}
create a sub-resource under a main-resource
POST /main-resource/{main-id}/sub-resouces: Which has the benefit of hierarchy, but in order to support this one needs to provide another set of endpoints(list, create, update, delete).
POST /sub-resouces?main={main-id}: Which has the benefit of having embedded id inside URL. A middleware can handle and inject provided values into request itself.
create a sub-resource with all parameters in body POST /sub-resources
Is providing a URI with main={main-id} query parameter embedded a good way to solve this or should I go with the route of hierarchical URI?
In a true REST environment the spelling of URIs is not of importance as long as the characters used in the URI adhere to the URI specification. While RFC 3986 states that
The path component contains data, usually organized in hierarchical form, that, along with data in the non-hierarchical query component (Section 3.4), serves to identify a resource within the scope of the URI's scheme and naming authority (if any). The path is terminated by the first question mark ("?") and number sign ("#") character, or by the end of the URI. (Source)
it does not state that a URI has to have a hierarchical structure assigned to it. A URI as a whole is a pointer to a resource and as such a combination of various URIs may give the impression of some hierarchy involved. The actual information of whether URIs have some hierarchical structure to it should though stem from link relations that are attached to URIs. These can be registered names like up, fist, last, next, prev and the like or Web linking extensions such as https://acme.org/rel/parent which acts more like a predicate in a Semantic Web relation basically stating that the URI at hand is a parent to the current resource. Don't confuse rel-URIs for real URIs though. Such rel-URIs do not necessarily need to point to an actual resource or even to a documentation. Such link relation extensions though my be defined by media-types or certain profiles.
In a perfect world the URI though is only used to send the request to the actual server. A client won't parse or try to extract some knowledge off an URI as it will use accompanying link relation names to determine whether the URI is of relevance to the task at hand or not. REST is full of such "indirection" mechanism in order to help decoupling clients from servers.
I.e. what is the difference between a URI like https://acme.org/api/users/1 and https://acme.org/api/3f067d90-8b55-4b60-befc-1ce124b4e080? Developers in the first case might be tempted to create a user object representing the data returned by the URI invoked. Over time the response format might break as stuff is renamed, removed and replaced by other stuff. This is what Fielding called typed resources which REST shouldn't have.
The second URI doesn't give you a clue on what content it returns, and you might start questioning on what benefit it brings then. While you might not be aware of what actual content the service returns for such URIs, you know at least that your client is able to process the data somehow as otherwise the service would have responded with a 406 Not Acceptable response. So, content-type negotiation ensures that your client will with high certainty receive data it is able to process. Maintaining interoperability in a domain that is likely to change over time is one of RESTs strong benefits and selling points. Depending on the capabilities of your client and the service, you might receive a tailored response-format, which is only applicable to that particular service, or receive a more general-purpose one, like HTML i.e.. Your client basically needs a mapping to translate the received representation format into something your application then can use. As mentioned, REST is probably all about introducing indirections for the purpose of decoupling clients from servers. The benefit for going this indirection however is that once you have it working it will work with responses issued not only from that server but for any other service that also supports returning that media type format. And just think a minute what options your client has when it supports a couple of general-purpose formats. It then can basically communicate and interoperate with various other services in that ecosystem without a need for you touching it. This is how browsers operate on the Web for decades now.
This is exactly why I think that this phrase of Fielding is probably one of the most important ones but also the one that is ignored and or misinterpreted by most in the domain of REST:
A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types. (Source)
So, in a true REST environment the form of the URI is unimportant as clients rely on other mechanisms to determine whether to use that URI or not. Even for so called "REST APIs" that do not really care about the true meaning of REST and treat it more like old-school RPC the question at hands is probably very opinionated and there probably isn't that one fits all solution. If your framework supports injecting stuff based on the presence of certain query parameters, use that. If you prefer the more hierarchical structure of URIs, go for those. There isn't a right or wrong in such cases.
According to the URI standard when you have a hierarchical relationship between resources, then better to add it to the path instead of the query. https://datatracker.ietf.org/doc/html/rfc3986#page-22 Sometimes it is better to describe the relation itself, not just the sub-resource, but that happens only if the sub-resource can belong to multiple main resources, which is n:m relationship.

Versioning related media types individually or in lockstep in a RESTful API

I'm developing a REST API around an ecommerce site and one of my resources is an Order which contains information like went it was made, the ID, the status, when it will be shipped, etc.
I have defined a media type for my Order resource like so:
application/vnd.myapp.order.v1+json
I also have defined another resource which is the status of an order, like so:
application/vnd.myapp.order-status.v1+json
My question is around the versioning of these media types. Seeing as they're related, would it make sense to version them in lockstep? For example, if the representation of the order resource changes and I create a application/vnd.myapp.order.v2+json, would it wise to also bump the version of the order-status media type to v2 as well? I'm also wondering if any there is a RESTful option with regards to the guidelines. I did have a look around online and couldn't really find anything talking about the best practice here, so any advice/opinions are appreciated.
I don't think mixing version and media type is a good idea.
In my opinion, you should separate it according to 'separate concerns principle' and 'single responsibility'.
https://en.wikipedia.org/wiki/Separation_of_concerns
https://en.wikipedia.org/wiki/Single-responsibility_principle
Many teams use header/url for versioning:
For example:
/api/v1/
/api/v2/
header {version:'v1'}
header {version:'v2'}
Then we can easily map the request with our need:
#RequestMapping(value="api/v1/books", consumes="application/json")
#RequestMapping(value="api/v2/books", consumes="application/json")
or
#RequestMapping(value="api/books",headers="version=v1", consumes="application/json")
#RequestMapping(value="api/books",headers="version=v2", consumes="application/json")
Although it seems useful it would be a violation of SoC and cause additional issues down the line as your API evolves.
Versioning your URLs is the better choice here, as URL is a perfect way to signal what type of resource is being dealt with and relation to the data it handles.
(To me introducing a custom header sounds much better design-wise then a custom versioned media type)
Custom media types are generally supposed to tell a consumer about the type of the data and its encoding scheme (e.g. xml vs json vs plain text and so on) and not how your fields are arranged from version to version while the encoding scheme is literally unchanged.
By choosing this path you would:
Force consumers of your API to tightly couple to that specific “representation” that creates maintenance issues on both sides.
Whenever you have multiple “versions” of your API co-existing at a given time - it introduce ambiguity when bodiless https methods such as DELETE or HEAD are used as the request information would simply be insufficient to correctly route your request, let alone the backend code completely.
It renders rels (Link Relation Types) less usable in their normal form (if you’d ever want to introduce them)

How to specify data security constraints in REST APIs?

I'm designing a REST API and I'm a big defender of keeping my URL simple, avoiding more than two nested resources.
However, I've been having second thoughts because of data security restrictions that apply to my APIs, that have been trying to force me to nest more resources. I'll try to provide examples to be more specific, as I don't know the correct naming for this situation.
Consider a simple example where I want to get a given contact restriction for a customer, like during what period my customer accepts to be bothered with a phone call:
So, I believe it's simpler to have this:
- GET /customers/12345
- GET /customers/12345/contacts
- GET /contacts/9999
- GET /contacts/9999/restrictions
- GET /restrictions/1
than this:
- GET /customers/12345
- GET /customers/12345/contacts
- GET /customers/12345/contacts/9999
- GET /customers/12345/contacts/9999/restrictions
- GET /customers/12345/contacts/9999/restrictions/1
Note: If there are more related resources, who knows where this will go...
The first case is my favourite because since all resources MUST have a unique identifier, as soon I have its unique identifier I should be able to get the resource instance directly: GET /restrictions/1
The data security restriction in place in my company states that not everyone can see every customers' info (eg: only some managers can access private equity customers). So, to guarantee that, the architects are telling me I should use /customers/12345/contacts/9999/restrictions/1 or /customers/12345/contact-restrictions/1 so that our data access validator in our platform has the customerId to check if the caller has access to it.
I understand the requirement and I see its value. However, I think that this kind of custom security informatio, because that's what I believe to be, should be in a custom header.
So, I believe I should stick to GET /restriction/1 with a custom header "customerId" with the value 12345.
This custom header would only be needed for the apis that have this requirement.
Besides the simpler URL, another advantage of the header, is that if an API didn't start with that security requirement and suddenly needs to comply to it, we could simply require the header to be passed, instead of redefining paths.
I hope I made it clear for you and I'll be looking to learn more about great API design techniques.
Thank you all that reached the end of my post :)
TL;DR: you are fighting over URI design, and REST doesn't actually offer guidance there.
REST, and REST clients, don't distinguish between your "simpler" design and the nested version. A URI is just an opaque sequence of bytes with some little domain agnostic semantics.
/4290c3b2-134e-4647-867a-214d0c866f29
Is a perfectly "RESTFUL" URI. See Stefan Tilkov, REST: I don't Think it Means What You Think it Does.
Fundamentally, REST servers are document stores. You provide a key (the URI) and the server provides the document. Or you provide a key, and the server modifies the document.
How this is implemented is completely at the discretion of the server. It could be that /4290c3b2-134e-4647-867a-214d0c866f29 is used to look up the tuple (12345, 9999, 1), and then the server checks to see if the credentials described in the request header have permission to access that information, and if so the appropriate representation of the resource corresponding to that tuple is returned.
From the client's perspective, it's all the same thing: I provide an opaque identifier in a standard way, and credentials in a standard way, and I get access to the resource or I don't.
the architects are telling me I should use /customers/12345/contacts/9999/restrictions/1 or /customers/12345/contact-restrictions/1 so that our data access validator in our platform has the customerId to check if the caller has access to it.
I understand the requirement and I see its value. However, I think that this kind of custom security information, because that's what I believe to be, should be in a custom header.
There's nothing in REST to back you up. In fact, the notion of introducing a custom header is something of a down check, because your customer header is not something that a generic component is going to know about.
When you need a new header, the "REST" way to go about it is to introduce a new standard. See RFC 5988 for an example.
Fielding, writing in 2008
Every protocol, every media type definition, every URI scheme, and every link relationship type constitutes prior knowledge that the client must know (or learn) in order to make use of that knowledge. REST doesn’t eliminate the need for a clue. What REST does is concentrate that need for prior knowledge into readily standardizable forms.
The architects have a good point - encoding into the uri the hints that make it easier/cheaper/more-reliable to use your data access validator is exactly the sort of thing that allowing the servers to control their own URI namespace is supposed to afford.
The reason that this works, in REST, is that clients don't depend on URI for semantics; instead, they rely on the definitions of the relations that are encoded into the links (or otherwise expressed by the definition of the media type itself).

How do you represent "thin" and "fat" versions of a RESTful resource?

How would you model a resource that can have two different representations. For example, one representation may be "thin" withe most of its related resources accessible by links. Another representation may be "fat" where most of its related resources are embedded. The idea being, some clients don't mind having to make many calls to browse around the linked resources, but others want to get the data all at once.
Consider a movie resource that is associated with a director, actors, etc. Perhaps the thin version of it has the movie title only, and to get the data for the director, list of actors, etc., one must make additional requests via the embedded links to them. Perhaps the fat version of it contains all the movie nested inside, including the director's data, the data for the various actor's, etc.
How should one model this?
I see a few options:
these two representations are really two different resources and require different URIs
these two representations are in fact the same resource, and you can select between the two representations via custom media types, for example application/vnd.movie.thin+json and application/vnd.movie.fat+json.
these two representations are in fact the same resource, and selecting the different representations should be done with query parameters (e.g. /movies/1?view=thin).
Something else...
What do you consider the proper approach to this kind of API?
You could use the prefer header with the return-minimal parameter.
I prefer using Content-Type for this. You can use parameters, too:
application/vnd.myapp; profile=light
The Fielding dissertation about REST tells you about the resource interface, that you have to bind your IRIs to resources, which are entity sets. (This is different from SOAP, because by there you usually bind your IRIs to operations.)
According to Darrel Miller, the path is for describing hierarchical data and the query string is for describing non-hierarchical data in IRIs, but we use the path and the query together to identify a resource inside an API.
So based on these you have two approaches:
You can say, that the same entity with fewer properties can be mapped to a new resource with an own IRI. In this case the /movies/1?view=thin or the /movies/1/view:thin is okay.
Pros:
According to the
RDF a
property has rdf:type of rdf:Property and rdfs:Resource either, and REST has connections to the semantic web and linked data.
It is a common practice to create an IRI for a single property, for example /movies/1/title, so if we can do this by a single property, then we can do this by a collection of properties as well.
It is similar to a map reduce we already use for collection of entites: /movies/recent, etc... The only difference, that by the collection of entities we reduce a list or ordered set, and by the collection of properties we reduce a map. It is much more interesting to use the both in a combination, like: /movies/recent/title, which can return the titles of the recent movies.
Cons:
By RDF everything has an rdf:type of rdfs:Resource and maybe REST does not follow the same principles by web documents.
I haven't found anything about single properties or property collections can be or cannot be considered as resources in the dissertation, however I may accidentally skipped that section of the text (pretty dry stuff)...
You can say that the same entity with fewer properties is just a different representation of the same resource, so it should not have a different IRI. In this case you have to put your data about the preferred view to somewhere else into the request. Since by GET requests there is no body, and the HTTP method is not for storing this kind of things, the only place you can put it are the HTTP headers. By long term user specific settings you can store it on the server, or in cookies maintained by the client. By short term settings you can send it in many headers. By the content-type header you can define your own MIME type which is not recommended, because we don't like having hundreds of custom MIME types probably used by a single application only. By the content-type header you can add a profile to your MIME type as Doug Moscrop suggested. By a prefer header you can use the return-minimal settings as Darrel Miller suggested. By range headers you can do the same in theory, but I met with range headers only by pagination.
Pros:
It is certainly a RESTful approach.
Cons:
Existing HTTP frameworks not always support extracting these kind of header params, so you have to write your own short code to do that.
I cannot find anything about how these headers are affecting the client and server side caching mechanisms, so some of them may not be supported in some browsers, and by servers you have to write your own caching implementation, or find a framework which supports the header you want to use.
note: I personally prefer using the first approach, but that's just an opinion.
According to Darrel Miller the naming of the IRI does not really count by REST.
You just have to make sure, that a single IRI always points to the same resource, and that's all. The structure of the IRI does not count by client side, because your client has to meet the HATEOAS constraint if you don't want it to break by any changes of the IRI naming. This means, that always the server builds the IRIs, and the client follows these IRIs it get in a hypermedia response. This is just like using web browsers to follow link, and so browse the web... By REST you can add some semantics to your hypermedia which explains to your client what it just get. This can be some RDF vocabulary, for example schema.org, microdata, iana link relations, and so on (even your own application specific vocab)...
So using nice IRIs is not a concern by REST, it is a concern only by configuring the routing on the server side. What you have to make sure by REST IRIs, that you have a resource - IRI mapping and not an operation - IRI mapping, and you don't use IRIs for maintaining client state, for example storing user id, credentials, etc...

REST resource with multiple views

We are trying to follow a quite strict idiom for our REST service however we have come across a situation where we have two clients who require different representations of the same resource. One is front-end and they would prefer a very minimal resource with only the fields they require and in a more flattened structure (for performance), the other requires all fields that we have in our data store in a heavily nested structure. What is the idiomatic way for REST services to deal with this given the canonical URL should be the same as they are accessing the same resource. We thought of adding projections to the request but with this the structure would still be quite nested which causes performance issues in the JS client as it will have to walk through the structure and flatten it, something that can be quite costly when the number of resources returned is high.
I would suggest there are two alternatives:
1) If the query field can vary, you could specify the fields (structure) you want as query parameters. This is common in REST APIs. With no specification, you would return a default list of fields. What should be default or not depends on the service, but in general the minimal set makes a better default for performance. In order to avoid listing all fields, something like fields=all could be used. In your case structure might make more sense.
2) You can encode the field request in a custom request headers. Some would argue that this is the more REST-ful approach as you're only modifying the format of the response and not the underlying action invoked, and therefore the URL should be the same.
In practice, most services prefer the first approach as it's considered more approachable.
Personally, I think it's a marginal choice. I prefer to encode the return media (JSON, HTML, XML, etc.) in the Accept header. Any decent developer has tools that make it easy enough to set the headers, but the fields query parameter idiom is, in my experience, far more prevalent and there's a great deal to be said for convention.
Note, if you use the headers approach, you should probably not use the Accept header for the structure/field specification. Add your own header if you go that route.