Custom Resources Hapi FHIR - web-services

I have a problem with custom resources. I'm doing a restful server to access to clinical information form a external database, and I have a custom resource: MyAppointment, with a custom attribute.
My question is, when a client uses my web service, need the client to have a class in his code identical that my MyAppointment.class for do this:
// Create a client (only needed once)
FhirContext ctx = new FhirContext();
IGenericClient client = ctx.newRestfulGenericClient("http://localhost:8080/restful-server-example/fhir");
// Invoke the client
Bundle bundle = client.search().forResource(Appointment.class)
.where(new StringClientParam("patient").matches().value("1232"))
.where(new StringClientParam("fechaDesde").matches().value("2"))
.where(new StringClientParam("fechaHasta").matches().value("2"))
.execute();
**MyAppointment** appo= (**MyAppointment**) bundle.getEntry().get(0).getResource();
If not, how can the client get de Custom Resource?
Thanks

That's the challenge with custom resources. At the moment, any implementation that uses custom resources isn't FHIR conformant and isn't going to interoperate with other FHIR solutions unless you have a specific site-specific agreement. So custom resources tend to work best in closed communities where everyone can use custom code. If you want to interoperate with the general community, you should use Basic.
We're exploring other alternatives for custom resources. However, those custom resources will likely be restricted to resources that don't cover space handled by existing resources. So, given that FHIR already has an Appointment resource, there wouldn't be support for introducing MyAppointment - the expectation is that you'd profile the existing Appointment resource and use constraints & extensions to reflect your local requirements. If you're finding that the existing Appointment resource simply can't be adapted to reflect your needs, please engage with the Patient Administration work group and share your issues. (And if you'd like to accelerate the work towards supporting custom resources in general, share your desires on http://chat.fhir.org.

Related

How does a multi-tenant application fit in Microservices based architecture?

I have a SaaS based multi-tenant monolith application (built with Django), that I want to divide into microservices based architecture. But I am not sure how to divide the application into correct partitions. And on what aspects should I take care of?
In case of monolith application, it's easy to understand that I have a tenant model that decides the schemas but how this will be done in microservices if I want each service to be multi-tenant? Or should I even make the services multi-tenant?
If you're already using OAuth and/or generating JWTs for user authentication/authorization, I'd recommend any new services that need tenant scoping to require a user access token be provided in requests just like your Django app. This lets you standardize how credentials and tenant scoping is expected to be passed, and verifying JWTs is a pretty easy process to implement.
That being said, it's also important to point out that you shouldn't require that services use access tokens or have any kind of tenant scoping at all. Not only is it possible that specific services don't require tenant scoping, but it's also possible that they might want to define a tenant differently from the main Django app (e.g. a simple tenant_id). For example, a payments service that only accepts a dollar amount and a credit card doesn't care what the tenant is and would be perfectly safe to call from the main Django application (of course you should prevent public access to the service too).
The best way to think about how new services should be designed is in a vacuum - without care for how other services are designed or how they store their data. Your service was built to perform a task and it defines for itself what parameters it needs to perform that task, how it executes that task, and how it stores the data it needs for future tasks. This independence from the design of other microservices in the stack is part of the power of designing service-oriented systems. It allows creators to pick the right tools for the job, and allows them to create meaningful features without needing to collaborate with dozens of team members that they often don't know.
Hope this helps, and good luck.

AWS API Gateway: When to create another API?

This conceptual question has crept into my mind after becoming more familiar with AWS. In general, I’m curious if there is a best-practice and/or convention as to when an API provider should group endpoints into a new, separate API (vs. lumping the endpoints into an existing API).
To illustrate, let’s say a Service creates digital wallet coupons on behalf of Manufacturers, to be redeemed by Consumers at a bunch of Mom & pop stores — some of the activities the Service might engage in include:
Receiving data from the Manufacturers (in order to build the digital coupons)
Providing a mechanism for Consumers to find and download coupons
Providing a way for the Mom & pop stores’ payment terminals to validate the coupons
And, oh by the way, the Service might also be required to ...
Implement a variety of endpoints, based on technologies involved (e.g., PassKit with Apple Wallet)
So?
With AWS, it’s easy to modularize one’s backend (e.g., have an RDS instance for the database, run a few lambda functions for microservices, etc.) and load balance it all. API Gateway adds to this in that each endpoint can point to different things (lambda functions, EC2 instances via HTTP proxy, etc.).
Consequently, one approach might be to define one API in AWS API Gateway and have all the endpoints underneath it:
API: “Master”
/coupon
POST = create a new one (for Manufacturers)
PUT = update an existing one (for Manufacturers)
GET = retrieve one (for Consumers)
/coupon/validate
POST = verify it’s still valid (Mom & Pop store use-case)
/apple-wallet
/{version}
/passes
... per documentation
/devices
... per documentation
But would it make more sense for the Service to shave off the /apple-wallet endpoint and create an entirely new, separate API?
Alternatively, if the Service was going to publish documentation for public developers to use, would it make sense to move the Manufacturer-relevant endpoints into a separate API altogether?
Since AWS makes the effort of splitting endpoints so simple via API Gateway, are there any standard practices for when you should (or should not)?
Thank you for any insights / opinions!
My two cents. Think about your end-user for your APIs. You will have different developer end-users for each API set.
Your ideal situation will have each developer end-user only seeing the APIs that are relevant to them. So you should split your APIs into different Gateways according to the end-users
In the theoretical situation you describe:
Create an API for Manufacturers so they can integrate with you to create coupons. If you do the integration internally it will be the corporate sales and presales people who talk to the manufacturers
The users for the Service and End User coupons might end up being the
same app developers that create an interface for both stores and
users. So create a coupon API for them
Separating both should also give you security benefits as you will protect the knowledge of your Manufacturer API from the users who might try to hack it

How to enforce authorization policies across multiple applications?

Background
I have a backoffice that manages information from various sources. Part of the information is in a database that the backoffice can access directly, and part of it is managed by accessing web services. Such services usually provides CRUD operations plus paged searches.
There is an access control system that determines what actions a user is allowed to perform. The decision of whether the user can perform some action is defined by authorization rules that depend on the underlying data model. E.g. there is a rule that allows a user to edit a resource if she is the owner of that resource, where the owner is a column in the resources table. There are other rules such as "a user can edit a resource if that resource belongs to an organization and the user is a member of that organization".
This approach works well when the domain model is directly available to the access control system. Its main advantage is that it avoids replicating information that is already present in the domain model.
When the data to be manipulated comes from a Web service, this approach starts causing problems. I can see various approaches that I will discuss below.
Implementing the access control in the service
This approach seems natural, because otherwise someone could bypass access control by calling the service directly. The problem is that the backoffice has no way to know what actions are available to the user on a particular entity. Because of that, it is not possible to disable options that are unavailable to the user, such as an "edit" button.
One could add additional operations to the service to retrieve the authorized actions on a particular entity, but it seems that we would be handling multiple responsibilities to the service.
Implementing the access control in the backoffice
Assuming that the service trusts the backoffice application, one could decide to implement the access control in the backoffice. This seems to solve the issue of knowing which actions are available to the user. The main issue with this approach is that it is no longer possible to perform paged searches because the service will now return every entity that matches, instead of entities that match and that the user is also authorized to see.
Implementing a centralized access control service
If access control was centralized in a single service, everybody would be able to use it to consult access rights on specific entities. However, we would lose the ability to use the domain model to implement the access control rules. There is also a performance issue with this approach, because in order to return lists of search results that contain only the authorized results, there is no way to filter the database query with the access control rules. One has to perform the filtering in memory after retrieving all of the search results.
Conclusion
I am now stuck because none of the above solutions is satisfactory. What other approaches can be used to solve this problem? Are there ways to work around the limitations of the approaches I proposed?
One could add additional operations to the service to retrieve the
authorized actions on a particular entity, but it seems that we would
be handling multiple responsibilities to the service.
Not really. Return a flags field/property from the web service for each record/object that can then be used to pretty up the UI based on what the user can do. The flags are based off the same information that is used for access control that the service is accessing anyway. This also makes the service able to support a browser based AJAX access method and skip the backoffice part in the future for added flexibility.
Distinguish between the components of your access control system and implement each where it makes sense.
Access to specific search results in a list should be implemented by the service that reads the results, and the user interface never needs to know about the results the user doesn't have access to. If the user may or may not edit or interact in other ways with data the user is allowed to see, the service should return that data with flags indicating what the user may do, and the user interface should reflect those flags. Service implementing those interactions should not trust the user interface, it should validate the user has access when the service is called. You may have to implement the access control logic in multiple database queries.
Access to general functionality the user may or may not have access to independant of data should again be controlled by the service implementing that functionality. That service should compute access through a module that is also exposed as a service so that the UI can respect the access rules and not try to call services the user does not have access to.
I understand my response is very late - 3 years late. It's worth shedding some new light on an age-old problem. Back in 2011, access-control was not as mature as it is today. In particular, there is a new model, abac along with a standard implementation, xacml which make centralized authorization possible.
In the OP's question, the OP writes the following re centralized access control:
Implementing a centralized access control service
If access control was centralized in a single service, everybody would be able to use it to consult access rights on specific entities. However, we would lose the ability to use the domain model to implement the access control rules. There is also a performance issue with this approach, because in order to return lists of search results that contain only the authorized results, there is no way to filter the database query with the access control rules. One has to perform the filtering in memory after retrieving all of the search results.
The drawbacks that the OP mentions may have been true in a home-grown access control system, in RBAC, or in ACL. But they are no longer true in abac and xacml. Let's take them one by one.
The ability to use the domain model to implement the access control rules
With attribute-based access control (abac) and the eXtensible Access Control Markup Language (xacml), it is possible to use the domain model and its properties (or attributes) to write access control policies. For instance, if the use case is that of a doctor wishing to view medical records, the domain model would define the Doctor entity with its properties (location, unit, and so on) as well as the Medical Record entity. A rule in XACML could look as follows:
A user with the role==doctor can do the action==view on an object of type==medical record if and only if the doctor.location==medicalRecord.location.
A user with the role==doctor can do the action==edit on an object of type==medical record if and only if the doctor.id==medicalRecord.assignedDoctor.id
One of the key benefits of XACML is precisely to mirror closely the business logic and the domain model of your applications.
Performance issue - the ability to filter items from a db
In the past, it was indeed impossible to create filter expressions. This meant that, as the OP points out, one would have to retrieve all the data first and then filter the data. That would be an expensive task. Now, with XACML, it is possible to achieve reverse querying. The ability to run a reverse query is to create a question of the type "What medical record can Alice view?" instead of the traditional binary question "Can Alice view medical records #123?".
The response of a reverse query is a filter condition which can be converted into a SQL statement, for instance in this scenario SELECT id FROM medicalRecords WHERE location=Chicago assuming of course that the doctor is based in Chicago.
What does the architecture look like?
One of the key benefits of a centralized access control service (also known as externalized authorization) is that you can apply the same consistent authorization logic to your presentation tier, business tier, APIs, web services, and even databases.

Purpose of the service layer

Am I correct in thinking that the purpose of a service layer includes the following?
thinning out of domain models (i.e. movement of certain functions like in caching, instantiation)
reduction in dependencies from domain models
API minimisation
Traditionally (when not using Domain Driven Design) the service layer, or 'business layer' as it is also called, is where you code all the business logic for your application. So, for example in an application that deals with giving out bank loans, the service layer is where the code goes that decides whether or not a certain loan should be given.
Obviously, the service layer would require some information about the applicant of the loan to be able to make a decision on her credibility. To retrieve this information, the business layer calls the 'data' or 'repository' layer, which deals with extracting and storing information into the database.
The service layer does not deal with matters like persistence or other infrastructural concerns.
If your design is domain-driven, anthares' answer is true.
In terms of domain-driven design for example the domain service layer is used for operations that cannot be defined in the context of you Domain objects. For example if you have an object CreditCard, a suitable operation in your service layer would be Issue a new Credit Card.
In bigger application is used the pattern Anemic Domain Models, where the domain objects are used only as data containers and the whole business logic is in your domain service layer (this is sometimes refered as anti-pattern, but may be very useful in big solution, with adding another abstraction layer).
In difference solution architectures and patterns, service layer may have difference purpose, though.
Service Layer as the name suggests provides services that are not directly responsibility of any other domain object.
Service Layer also helps in decoupling of responsibilities. Service Layer forms the middle part between Database/persistence layer and the Client/UI/Web layer.
Properly designing the Service Layer allows it to be used from any client be it a Web Client or a Web Service (SOA) or Mobile device.

Exposing Rich Domain Objects as a service

I’ve been trying to wrap my head around how to expose my domain objects to the client. Whether I’m using a rich client or I’m using the web, I want to use the MVP and repository patterns.
What I’m trying to wrap my head around is how I expose my repository and model, which will be on the server. Is it even possible to expose complex business objects that have state via a web service, or will I have to use a proprietary technology that is not language/platform agnostic, like .Net remoting, EJB, COM+, DCOM, etc?
Some other constraints are that I don’t want to have to keep loading the complex domain object from the database or passing it all over the wire every time I want to do an operation. Some complex logic might be that certain areas of the screen might be disabled or invisible based on the users permissions in combination with the state of the object. Validation and error message information will also need to be displayed to the user. I want to be able to logically call a lot of my domain object operations as if it were running on the same machine.
With the web, you have free rein. You don’t have to expose your objects across service boundaries, so you can make them a rich as you would like. I’m trying to create an N-teir architecture that is rich and works when the client calling the model is on a different machine.
You can expose your domain objects like any other object through REST or web services. I think key is to understand that you will have to expose services that provide business value in a single call, and these do not necessarily map 1:1 to your repositories. So while you on the server may expect a single service call to use multiple repositories and perform various aggregations, the things you expose over any kind of web-service should be more or less complete results. The operations you expose on the service should not expose individual repositories but rather focus on meaningful operations that provide a given business value.
I hope this helps somewhat.
You can use a SOAP formater for .Net remoting,
but the resulting service will probably be hard
to consume as a service, and it will surly be very chatty.
If you want your domain model to be consumed as a service,it should be designed as a service.
As stated in domain driven design, a service is stateless, so it won't expose your objects directly. Your service should expose methods that provides meaningful business operations that will be executed as a single unit.
Usually consider that the model in your client is in a different bounded context because its concerns will be a bit different from the one on the server.
What I’m trying to wrap my head around
is how I expose my repository and
model, which will be on the server. Is
it even possible to expose complex
business objects that have state via a
web service, or will I have to use a
proprietary technology that is not
language/platform agnostic, like .Net
remoting, EJB, COM+, DCOM, etc?
A good domain model is going to be highly behavioral and designed around the problem domain (and your discussions with domain experts), I'd thus argue against designing it to be exposed to remote consumers (in the same way that designing it from the database or GUI first is a bad idea).
Instead I'd look at using a style like REST or messaging and decide on the interface you want to expose and then map to/from the domain. So if you went with REST you'd design your resources and API (URL's, representations, etc.) and then you'd need to fulfill it from the domain model.
If this becomes un-natural then you can always have multiple models, for example mapping a seperate read-only presentation specific model to the same data-source (or which wraps the complex behavioral domain model) is an approach I've used several times.
Some other constraints are that I
don’t want to have to keep loading the
complex domain object from the
database or passing it all over the
wire every time I want to do an
operation
Look at caching in HTTP and supporting multiple representations for a resource, also look at caching within your data-access solution.
Validation and error message
information will also need to be
displayed to the user. I want to be
able to logically call a lot of my
domain object operations as if it were
running on the same machine.
You can either represent this as a resource or more likely look at HTTP status codes and the response bodies you'd want to use in those situations.