Proper way of implementing HATEOAS with ServiceStack - web-services

I know how mythz generally feels about HATEOAS, but let's say that I have to follow the HATEOAS principles in my REST services and add links ("self", "parent", and other possible relations) to my DTOs.
Links like "self" and "parent" contains paths to the resources and those paths are of course related to my routes.
I'm using the following project/deployment structure for my ServiceStack REST service. If that matters, I'm using ServiceStack 3.9.71.
Service Gateway Assembly:
defines my DTOs. Each DTO has a factory creating that DTO from the corresponding domain object
defines operations and their routes
Service Implementation Assembly:
uses ServiceGateway to get DTO definitions and access their factories
does whatever domain logic requires and create the corresponding DTOs through the afore mentioned factories
Service Interface Assembly:
define my REST services and
calls ServiceImplementation from ServiceStack's HttpHandler, according to REST verbs (GET, POST, ...)
WHERE would be the proper place to add link information to my DTOs?
Option1:
In my Service Gateway, when I build the DTOs themselves. It seems logical:
I know what I need to know about my domain objects and I can easily
build the links. Except that my DTOs are now all including an
additional member (Links) and building those links forces me to
explicitly provide paths/routes (i.e. hard code them). Seems to lead
to a maintenance nightmare.
Option2:
In my Service Interface assembly, where I have the request context and
I know my routes. I can encapsulate whatever my Service Implementation
returns in a meta-object containing the response and a link
collection. However, to build that link collection, I sometimes need
information available at the domain (i.e. Service Implementation)
level. The big "con" side for me is that it creates a new additional
and artificial level in all my responses. Could be seen as a way to
standardize response formats but I don't like it.
Option3:
My hope is that I can write a wrapper generically "injecting" a "Links" member to all the DTOs
I return by hooking somewhere into ServiceStack in my Service Interface assembly. I haven't
investigated much in that direction because I feel I could be wrong on
the whole approach here.
Any advise / suggestion welcome. Thanks to all.

I'm not sure If I'm suggesting you option1 or option3, but this Is what I came out after trying to do the same thing.
I started from this answer.
Now you can access route metadata directly from filters.
So my current approach is:
=> Services create the dto responses and the next collection of hypermedia links that will be attached to the response. In this level you know the "operations" by type but not "how" you will build the routes. I think it is coherent that domain level deals with workflows of operations.
=> Within a response filter I get the available routes from Metadata, and build the routes from dto properties by convention. Finally routes are added to http header.
Caveats:
I'm mapping 1 dto - 1 route. This approach could be more difficult in other cases.

Related

Django Rest Framework communicating with mobile app instances

I would like to build a REST Service which exchanges JSON messages with instances of a mobile app for registering patron traffic in physical locations of (public and academic) libraries.
I plan on using Django Rest Framework, and using Django and DRF for the first time, have some questions (rather, recommendation requests). I have read the tutorials and followed some of them, and it looks very promising indeed.
As I am quite confident with Object oriented coding in Python, I will be using class based views. Any reason not to?
The intended usage of the system will include many different libraries with their own ids, users and properties. The data model behind is thus fairly complex, and implemented with MySQL. I feel I will have better control on the data exchange, updates inserts and selects, with custom SQL queries, and would like the DRF to handle mostly authentication and the routing of messages to and from the instances of the mobile app. Is this a misconception on my part, and would it be better to let DRF handle all database-involved aspects?
Given that I follow the custom SQL approach:
As (authenticated) user IDs are interwoven with the rest of the activities (e.g. we would like to know which of the authenticated users stands behind a certain registration of activity), it would seem "simple" to use a single database for both the business model itself and the DRF-controlled aspects. Is it recommended ? Are there any aspects that need to be considered here?
I have not found similar projects to be learning from. Anybody knows a similar project?
I know it is not very concrete, but hope to elevate my understanding a bit while endeavoring on the task.
Michael
I have tried to keep this as unopinionated as possible. Mostly reffering from Django's and DRF's documentation to make sure.
Class based views have some implicit code flows, need method overrides at some places. But since you are quite comfortable with Class based views, it is far more superior in the following ways: cleaner code, much more DRY compliant than function based, easier to extend, keeps your code base more maintainable as it grows.
Django's ORM is pretty powerful and if used correctly it can provide a vareity of capabilities.
Unless your authentication system is very complex and needs to scale independently, having everything in the same DB makes sense. The chatter reduces and you will be able to utilise powerful Django and DRF's features.

Structuring Google Cloud Functions project

I have a REST API that I'd like to port to run as a collection of cloud functions. I'm wondering how to split up the different endpoints in the best way, and how much to rename endpoints to fit the GCF model.
For example, I have the following types of request.
GET /images
GET /images/<image_id>
POST /images
If this was implemented with GCF, these would all fall under the same function images, and then I would need to implement some routing based on HTTP method, plus a pattern match for <image_id>, etc..
I could however choose to implement something like...
GET /images
GET /image/<image_id>
POST /createImage
...so that each endpoint has a distinct function that is invoked. This seems more appropriate from a cloud functions point of view, but not at all appropriate from a RESTful design point of view.
What are the trade-offs for implementing cloud functions in one or the other of these ways?

C++ RESTful Service Router Pattern

I've been searching around for the past few days trying to find a good article that addresses what I'm trying to do, but haven't really found much yet. Most point me in the direction of pre-existing C++ MVC frameworks.
I have a C++ application with a tiny embedded web server that responds to HTTP requests. What I want to do is create a routing pattern in which I can define service end points and the application will be able to use the proper C++ controller class.
For example, I could define my service end points like the following in a text file:
POST /login UserController::login()
GET /user UserController::get()
GET /dashboard DashboardController::get()
And have the C++ application call the appropriate class and static method based on the service I'm invoking. So in the case of the above example, if I submit an HTTP POST request to /login, then the Router should invoke UserController::login(). Service end points don't necessarily have to be defined in a text file, there could be another in-memory data structure they can be defined in.
I've been considering something like the Proxy pattern: http://en.wikipedia.org/wiki/Proxy_pattern
Or I was looking at this pattern: http://gameprogrammingpatterns.com/service-locator.html
Before going too far down a specific implementation I wanted to get some feedback from others on how they might go about implementing such a requirement?
Thanks!

Ignore properties if not authenticated or some authentication rule

I have a service in ServiceStack with a DTO that returns multiple properties, but some can only be returned if the person is authenticated, or if some rule.
How can I do this?
The attribute can only be used in class or method and not a property.
There are many ways to ignore properties in serialization, using Conditional Serialization is likely the most useful here.
But I'd personally avoid using bespoke serialization features and just use vanilla C# to set the properties you don't want to return to null, either within your service or in one of the Custom Response Filters and Hooks.

How to use servlet filters with Pax-Web and the whiteboard pattern

Registering filters with whiteboard.
Hi,
I'm trying to use a Servlet filter with a servlet. I'm using Pax-Web 3.0, Declarative services and whiteboard.
I have to declarative service components (one for the servlet and one for the filter), and it seems to work fine.
Looking at the documentation I see the following sentence:
For URL Patterns, the pattern registered must be already mapped,
either as Resource or a Servlet alias - e.g there should already be a
Resource or aServlet registered to the path /foo. For Servlet names,
the names used should have been the name that has been explicitly
given to the Servlet (as servlet-name), when registering.
How can I guarantee that in a whiteboard setting? I have no idea when the servlet actually gets registered. I guess I can list the servlet as a dependency of the filter, but that makes it tricky to use the filter for multiple servlets.
Is there a better way?
regards, Frank
It seems highly unlikely that this is an issue. I expect that the sentence from the documentation indicates that your filter just never get called when there is no destination for the path. I.e. the filter is only called when there is a valid destination (a resource or servlet). A basic aspect of the whiteboard is that you should not care about these issues. It is the responsibility for the whiteboard to handle the http service, the filters, and the servlets in any possible registration order. If not ... it needs a serious issue raised.
I have not looked at the code but I am a heavy user of the whiteboard + filter + servlet + DS and never have seen an issue.