Understanding where to put constraints validation for REST api service using Spring - spring

I'm working on a REST api for a model having the following entities:
A Team cannot exists if it has no relationships with a Course and a Student. At the beginning, I created an endpoint for the teams (API/teams) for the CRUD operations. Now I ended up moving all the CRUD operations for the teams under the following URLs:
/API/courses/{courseId}/teams
The same has been done for Machine that cannot exists without any relationships with a Team and Student, so any CRUD operation should be done to the following:
/API/courses/{courseId}/teams/{teamId}/virtual-machines
This makes sense to me, since every time I need to perform an operation on a Machine I have to verify the constraint for which the Machine is owned by a Team related to a Course. For this reason, If I continued to perform any operation on URLs like /API/teams I should have requested the course and team ids to verify those contraints in the request body.
Having said this, my CourseController invokes a VirtualMachineService for all the operations on the Machine entity. What it seems odd to me is that each signature of every method in the VirtualMachineService need to have the course and the team id to verify the above constraints. This caused to have lots of duplicated code in every method.
Are my design choices correct?
The CourseController only have to invoke the methods of VirtualMachineService and to validate the parameters coming from the requests body.
Should those constraints validation be done inside the controller or inside the service?

Neither Configuration nor Model are entities. Entities are classes from the domain (real world representations related to project, if you will), not every class you use.
REST doesn't directly care about your entity model (meaning graph) but you should follow the guidelines for specifying REST endpoints which is
different endpoint for
/courses/... and /teams/... - don't mix these. Any constraints you would like to apply are applied at the backend and have nothing to do with endpoint definitions.
Validation guide https://www.baeldung.com/spring-mvc-custom-validator

Related

Defining two separate API endpoints for essentially the same logic just for the sake of avoiding REST anti-patterns?

Suppose we have a M:M relationship between a User model and a Project model in a project management SaaS. Naturally we have a pivot table mapping users to projects. An entry is deleted either if the user leaves or if the project manager removes that user from the project.
Even though the final result is essentially the same (i.e., the entry is deleted), I imagine it would be better to distinguish between these two actions by defining two separate API endpoints as follows:
user leaves project
route DELETE /users/{id}/projects/{id}
action UserProjectController#destroy($id) where $id refers to the project
project manager removes user
route DELETE /projects/{id}/participants/{id}
action ProjectParticipantController#destroy($id) where $id refers to the user
Should I ignore Cruddy by Design and RESTful design principles and simply define leave() join() remove() actions instead and use verbs in the URIs? like so:
POST /projects/{id}/join
POST /projects/{id}/leave
POST /projects/{id}/participants/{id}/remove
join,leave,remove are arguably RPC rather than REST. Pivot tables etc are how the domain is implemented and are irrelevant to the caller of the API, which works at the domain level. How do the URLs map to your domain model?
If Project has one or more User why not just use
/projects/{id}/
to manage everything about Project and Participant instances?
User is in a Project but only if
/projects/{id}/participants/{id}
has been called.
FWIW,
DELETE /users/{id}/projects/{id}
looks like it's deleting the Project instance owned by a User as the Project object has participants but the User doesn't use that terminology. Perhaps it would be:
DELETE /users/{id}/projects/{id}/participants
for consistency with the domain model.
However it seems much easier to just use Project to manage Project instances. Removing a User from a Project using the User API seems a convenience that complicates the backend and doesn't really match the Project terminology. That would mean only having UserController and ProjectController classes.
You would have to consider whether a Participant id is the same as a User id and whether the pivot table handles that but that won't affect the API. The API should be an intuitive representation of your domain model.
Something to consider: how would you do it on the web?
Even though the final result is essentially the same (i.e., the entry is deleted), I imagine it would be better to distinguish between these two actions by defining two separate API endpoints
So on the web, you might well have two different forms that are used to "achieve the same result", but that doesn't necessarily mean that the forms should target different resources.
POST /foo
Content-Type: application/x-www-form-urlencoded
action=UnsubscribeUser&otherArguments=....
POST /foo
Content-Type: application/x-www-form-urlencoded
action=CancelProject&otherArguments=....
"One resource or two resources" isn't a question of right or wrong, but rather a question of trade-offs.
POST /projects/{id}/join
POST /projects/{id}/leave
POST /projects/{id}/participants/{id}/remove
That's also "fine"; again, it's a question of trade offs. The machines don't care that your identifiers have a verb in the URI.
They do, somewhat, care whether or not the identifier for reading is the same as the identifier for writing. See RFC 7234.
But it's perfectly reasonable to say that having semantically significant URI spellings in the access log or browser history are more important to our long term success than cache-invalidation.
Keep firmly in mind that DELETE - in the context of HTTP - does not mean the same thing as DELETE in the context of SQL; we're talking about two different name spaces with their own semantics.
HTTP DELETE is of the transfer of documents over a network domain. The fact that the implementation of your handler includes a SQL DELETE is completely irrelevant.
Relatively few resources allow the DELETE method -- its primary use is for remote authoring environments, where the user has some direction regarding its effect.
It is OK to use POST.

Creational adapter

I have a lot of code like this
additional_params = {
date_issued: pending.present? ? pending.date_issued : Time.current,
gift_status: status,
date_played: status == "Opened" ? Chronic.parse("now") : (opened.present? ? opened.date_played : nil),
email_template: service&.email_template,
email_text: service&.email_text,
email_subject: service&.email_subject,
label: service&.label,
vendor_confirmation_code: service&.vendor_confirmation_code
}
SomeService.new(reward, employee: employee, **additional_params).create
The same pattern applies to many models and services.
What is the name of this pattern?
How to refactor the current solution?
Is there a gem to solve this kind of solution? Like draper or something else
To me, that looks a bit like a god object for every type of entity. You expect your service to take care of everything related to your entity. The entity itself just acts as a data container and isn't responsible for its data. That's called an anemic model.
First of all, you need to understand that there can be several representations of the same entity. You can have several different classes that represent a user. On the "List user" page, the class contains just a subset of the information, maybe combined with information from the account system (last login, login attempt etc). On the user registration page, you have another class as it's not valid to supply all information for the user.
Those classes are called data transfer objects. Their purpose is to provide the information required for a specific use case and to decouple the internal entity from the external API (i.e. the web page).
Once you have done that, your service classes will start to shrink and you need fewer custom parameters for every method call.
Now your service class has two responsibilities: To manage all entities and to be responsible for their business rules.
To solve that, you should start to only modify your entities through behaviors (methods) and never update the fields directly. When you do so, you will automatically move logic from your service class to your entity class.
Once that is done, your service classes will be even cleaner.
You can read about Domain Driven Design to get inspired (no need to use DDD, but get inspired by how the application layer is structured in it).
You can try the builder pattern. I am not familiar with a ruby gem, but you can find information here: https://en.wikipedia.org/wiki/Builder_pattern and https://en.wikipedia.org/wiki/Fluent_interface

Proper RESTful way to create children in Laravel (Parent / Child) relationships

Not sure this is specific to Laravel but what is the proper RESTFUL way to handle creating a child of a parent with Laravel. For example I have a Car that can have many Drivers (hasMany) and Drivers belong to one Car (belongsTo). If I want to create a Driver whose parent is Car #1 does the CarController.php have the responsibility to create the driver: /car/1/driver/create or do I use /driver/create/car/1 and keep the responsibility within DriverController.php?
Right now I'm doing /driver/create/1 (where #1 represents the Car) which feels wrong but I'm not clear about what the RESTFUL way should be. TIA.
There really isn't a proper way of implementing nested resources in REST as it doesn't really care. There are arguments for and against nested resources, however, there are some generally accepted implementations and the agreement that whatever you decide on, be consistent.
I utilise nested resources, but only a single level of nesting and no more. So for example:
GET /cars/{carId}/drivers/{driverId}
However, I would avoid the following:
GET /cars/{carId}/drivers/{driverId}/incidents
If you have multiple nested resources, consider obtaining the nested resource through the parent resource:
GET /cars/{carId}/drivers/ // Get all drivers for the car
GET /drivers/{driverId}/incidents // Get all incidents for the driver
Arguably nested resource URLs can convey more meaning than a single resource URL at a glance. e.g.
GET /cars/{carId}/drivers/{driverId} // more meaningful
GET /drivers/{driverId} // less meaningful
With the second URL above, I do not know which car the requested driver is associated with until the resource is returned. That being said /drivers/{driverId} can still be applicable and useful to have depending on your use case.
A use case for a /drivers endpoint would be if you can create new drivers that are not yet associated with a car.
In response to your question of how to create a driver, I would consider the following use cases;
Create a driver without an association to a car
POST /drivers
Create a driver with an association to a car
POST /cars/{carId}/drivers
POST /drivers
For the POST /drivers endpoint you would use a DriverController and pass your Driver information to the store method. The validation rules in the store method would allow for an optional car_id parameter as part of the request. This would allow you to either associate a driver with a car at creation, or not.
For the POST /cars/{carId}/drivers endpoint, you would use a CarDriverController (or a DriverController in a Cars subfolder if often seen) and pass your Driver information to the store method. A car_id paramter would not be required in the request as the associated car would be obtained from the {carId} passed in the URL.
For updating your driver resources, you can follow the same principle just amending your HTTP verbs and creating the appropriate routes.
PUT /drivers/{driverId}
DriverController#update
PUT /cars/{carId}/drivers/{driverId}
CarDriverController#update
If you decided to implement both methods for creating drivers and you find duplicate code, consider refactoring it to a service.
Update 1
For #2 POST /cars/{carId}/drivers is the store endpoint does that make GET /cars/{carId}/drivers/create the create endpoint? And similarly for POST /drivers creation endpoint GET /drivers/cars/{carId}?
If you're working with blade views and following the Laravel conventions then your form to create a new driver for a given car would be found at GET /cars/{carId}/drivers/create or GET /drivers/create.
And it sounds like relationships should always get a separate controller.
Ideally yes as most applications are nothing more than CRUD and so everything can be mapped to one of the 7 controller actions. This keeps things clean and simple and responsibilities separate.
Take a look at this video by Adam Wathan which explains how to map what you think are custom actions to one of the 7 basic Laravel actions. Bit lengthy at 40 minutes but well worth a watch.
POST /cars/1/driver.
no interest in specifying the action (create). the method (post) already does it.

updates to entity,domain driven design

Lets say I have an order which got updated on the UI with some values (they could be ok/not ok to ensure save)
1. How do we validate the changes made? Should the DTO which carries the order back to service layer be validated for completeness?
Once the validation is complete? How does the service return the validation errors? Do we compose a ReponseDTO object and return it like
ResponseDTO saveOrder(OrderDTO);
How do we update the domain entity order? Should the DTO Assembler take care of updating the order entity with the latest changes?
If we imagine a typical tiered' approach, ASP .NET on Web Server, WCF on Application Server.
When the Order form is updated with data on the web and saved. The WCF receives a OrderDTO.
Now how do we update the order from DTO? Do we use an assembler to update the domain object with changes from DTO? something like
class OrderDTOAssembler {
updateDomainObject(Order, OrderDTO)
}
I will try answer some of your questions from my experience and how I should approach your problem.
First I should not let DTO conduct any validations, but just plain POCO DTO's usually have different properties with specific datatypes, so some kind of validation is done. I mean you have to apply an integer street number and string for street name etc.
Second as you point out. Let a ORderDTOAssembler convert from OrderDTO to Order and vice versa. This is done in the application layer.
Third I would use Visitor pattern Validation in a Domain Driven Design like the example. The OrderService will use an IOrderRepository to save/update the order. But using the visitor-validation approach the OrderService vill call Order.ValidatePersistance (see link in example - but this is a extension method that is implemented in infrastructure layer since it has "db knowledge") to check its state is valid. If true, then we to IOrderRepository.Save(order).
at last, if Order.ValidatePersistance fails we get one or more BrokenRules messages. These should be returned to client in a ResponseDTO. Then cient can act on messages and take action. Problem here can be that you will have a ResponseOrderDTO messages but maybe (just came up with this now) all your ResponseDTO can inherit from ResponseBaseDTO class that expose necessary properties for delivering BrokenRule messages.
I hope you find my thoughts useful and good luck.

What exactly is the model in MVC

I'm slightly confused about what exactly the Model is limited to. I understand that it works with data from a database and such. Can it be used for anything else though? Take for example an authentication system that sends out an activation email to a user when they register. Where would be the most suitable place to put the code for the email? Would a model be appropriate... or is it better put in a view, controller, etc?
Think of it like this. You're designing your application, and you know according to the roadmap that version 1 will have nothing but a text based command line interface. version 2 will have a web based interface, and version 3 will use some kind of gui api, such as the windows api, or cocoa, or some kind of cross platform toolkit. It doesn't matter.
The program will probably have to go across to different platforms too, so they will have different email subsystems they will need to work with.
The model is the portion of the program that does not change across these different versions. It forms the logical core that does the actual work of whatever special thing that the program does.
You can think of the controller as a message translator. it has interfaces on two sides, one faces towards the model, and one faces towards the view. When you make your different versions, the main activity will be rewriting the view, and altering one side of the controller to interface with the view.
You can put other platform/version specific things into the controller as well.
In essense, the job of the controller is to help you decouple the domain logic that's in the model, from whatever platform specific junk you dump into the view, or in other modules.
So to figure out whether something goes in the model or not, ask yourself the question "If I had to rewrite this application to work on platform X, would I have to rewrite that part?" If the answer is yes, keep it out of the model. If the answer is no, it may go into the model, if it's part of the essential logic of the program.
This answer might not be orthodox, but it's the only way I've ever found to think of the MVC paradigm that doesn't make my brain melt out of my ear from the meaningless theoretical mumbo jumbo that discussions about MVC are so full of.
Great question. I've asked this same question many times in my early MVC days. It's a difficult question to answer succintly, but I'll do my best.
The model does generally represent the "data" of your application. This does not limit you to a database however. Your data could be an XML file, a web resource, or many other things. The model is what encapsulates and provides access to this data. In an OOP language, this is typically represented as an object, or a collection of objects.
I'll use the following simple example throughout this answer, I will refer to this type of object as an Entity:
<?php
class Person
{
protected $_id;
protected $_firstName;
protected $_lastName;
protected $_phoneNumber;
}
In the simplest of applications, say a phone book application, this Entity would represent a Person in the phone book. Your View/Controller (VC) code would use this Entity, and collections of these Entities to represent entries in your phone book. You may be wondering, "OK. So, how do I go about creating/populating these Entities?". A common MVC newbie mistake is to simply start writing data access logic directly in their controller methods to create, read, update, and delete (CRUD) these. This is rarely a good idea. The CRUD responsibilities for these Entities should reside in your Model. I must stress though: the Model is not just a representation of your data. All of the CRUD duties are part of your Model layer.
Data Access Logic
Two of the simpler patterns used to handle the CRUD are Table Data Gateway and Row Data Gateway. One common practice, which is generally "not a good idea", is to simply have your Entity objects extend your TDG or RDG directly. In simple cases, this works fine, but it bloats your Entities with unnecessary code that has nothing to do with the business logic of your application.
Another pattern, Active Record, puts all of this data access logic in the Entity by design. This is very convenient, and can help immensely with rapid development. This pattern is used extensively in Ruby on Rails.
My personal pattern of choice, and the most complex, is the Data Mapper. This provides a strict separation of data access logic and Entities. This makes for lean business-logic exclusive Entities. It's common for a Data Mapper implementation to use a TDG,RDG, or even Active Record pattern to provide the data access logic for the mapper object. It's a very good idea to implement an Identity Map to be used by your Data Mapper, to reduce the number of queries you are doing to your storage medium.
Domain Model
The Domain Model is an object model of your domain that incorporates behavior and data. In our simple phone book application this would be a very boring single Person class. We might need to add more objects to our domain though, such as Employer or Address Entities. These would become part of the Domain Model.
The Domain Model is perfect for pairing with the Data Mapper pattern. Your Controllers would simply use the Mapper(s) to CRUD the Entities needed by the View. This keeps your Controllers, Views, and Entities completely agnostic to the storage medium. This also allows for differing Mappers for the same Entity. For example, you could have a Person_Db_Mapper object and a Person_Xml_Mapper object; the Person_Db_Mapper would use your local DB as a data source to build Entities, and Person_Xml_Mapper could use an XML file that someone uploaded, or that you fetched with a remote SOAP/XML-RPC call.
Service Layer
The Service Layer pattern defines an application's boundary with a layer of services that establishes a set of available operations and coordinates the application's response in each operation. I think of it as an API to my Domain Model.
When using the Service Layer pattern, you're encapsulating the data access pattern (Active Record, TDG, RDG, Data Mapper) and the Domain Model into a convenient single access point. This Service Layer is used directly by your Controllers, and if well-implemented provides a convenient place to hook in other API interfaces such as XML-RPC/SOAP.
The Service Layer is also the appropriate place to put application logic. If you're wondering what the difference between application and business logic is, I will explain.
Business logic is your domain logic, the logic and behaviors required by your Domain Model to appropriately represent the domain. Here are some business logic examples:
Every Person must have an Address
No Person can have a phone number longer than 10 digits
When deleting a Person their Address should be deleted
Application logic is the logic that doesn't fit inside your Domain. It's typically things your application requires that don't make sense to put in the business logic. Some examples:
When a Person is deleted email the system administrator
Only show a maximum of 5 Persons per page
It doesn't make sense to add the logic to send email to our Domain Model. We'd end up coupling our Domain Model to whatever mailing class we're using. Nor would we want to limit our Data Mapper to fetch only 5 records at a time. Having this logic in the Service Layer allows our potentially different APIs to have their own logic. e.g. Web may only fetch 5, but XML-RPC may fetch 100.
In closing, a Service ayer is not always needed, and can be overkill for simple cases. Application logic would typically be put directly in your Controller or, less desirably, In your Domain Model (ew).
Resources
Every serious developer should have these books in his library:
Design Patterns: Elements of Reusable Object-Oriented Software
Patterns of Enterprise Application Architecture
Domain-Driven Design: Tackling Complexity in the Heart of Software
The model is how you represent the data of the application. It is the state of the application, the data which would influence the output (edit: visual presentation) of the application, and variables that can be tweaked by the controller.
To answer your question specifically
The content of the email, the person to send the email to are the model.
The code that sends the email (and verify the email/registration in the first place) and determine the content of the email is in the controller. The controller could also generate the content of the email - perhaps you have an email template in the model, and the controller could replace placeholder with the correct values from its processing.
The view is basically "An authentication email has been sent to your account" or "Your email address is not valid". So the controller looks at the model and determine the output for the view.
Think of it like this
The model is the domain-specific representation of the data on which the application operates.
The Controller processes and responds to events (typically user actions) and may invoke changes on the model.
So, I would say you want to put the code for the e-mail in the controller.
MVC is typically meant for UI design. I think, in your case a simple Observer pattern would be ideal. Your model could notify a listener registerd with it that a user has been registered. This listener would then send out the email.
The model is the representation of your data-storage backend. This can be a database, a file-system, webservices, ...
Typically the model performs translation of the relational structures of your database to the object-oriented structure of your application.
In the example above: You would have a controller with a register action. The model holds the information the user enters during the registration process and takes care that the data is correctly saved in the data backend.
The activation email should be send as a result of a successful save operation by the controller.
Pseudo Code:
public class RegisterModel {
private String username;
private String email;
// ...
}
public class RegisterAction extends ApplicationController {
public void register(UserData data) {
// fill the model
RegisterModel model = new RegisterModel();
model.setUsername(data.getUsername());
// fill properties ...
// save the model - a DAO approach would be better
boolean result = model.save();
if(result)
sendActivationEmail(data);
}
}
More info to the MVC concept can be found here:
It should be noted that MVC is not a design pattern that fits well for every kind of application. In your case, sending the email is an operation that simply has no perfect place in the MVC pattern. If you are using a framework that forces you to use MVC, put it into the controller, as other people have said.

Resources