I have just starting learning the MVC pattern today (for gui applications, not web), and have a few questions on where data validation should take place.
From what i have read, it seems like most people are saying that all the validations should take place on the controller, and the model should pretty much only hold the state of the data. However, it seems like in some situations it would make more sense to do the verification in the model.
For example, lets say that a client changes the ipv4 address of the server they want to connect to from the gui. We want to verify that this is in fact an ipv4 address, and not just random characters. If the ip address is valid, then we want to change that data in the model to the new ip address, and if it isn't valid we want to have the view display an error (or something).
If you did the verification in the controller, then if in the future you decided you wanted to have a different controller/view (because from what i can tell, they are coupled pretty closely together), you would have to make sure to include this same verification code in both controllers, and would thus have to manage two pieces of the same code. That would of course be more prone to bugs then managing just one piece of code, like if the verification was done in the model.
Should i be doing it this way? Or am i missing that makes doing it in the controller make more sense? Or should some data be handled in the model, and some data handled in the controller?
Thanks
I guess that at the model the verification is always necessary. Some times would be nice to have also in the view so that the user would be event not allowed to input something other than what the field is asking for. One way or the other, generic verification like IP addresses validation make's a great candidate to be a global/static/utility method to be used, not only in the view and in the model but in several different models. Sometimes it can even be shared between client's view components and server components like in a GWT application
Related
I'm developing this JavaEE REST microservice oriented CQRS + EventSourcing app, I have this entity (Artwork) with many fields and I have to record each update to this entity according to EventSourcing pattern (basically each update creates a new event, the artwork is then rebuild using these events).
My approach basically works, but I'm stuck with a "compliance" towards HTTP standards, basically I want to avoid a "generic" update in which you update the whole entity because it will be a mess to handle each single field update (and consequent event generation).
So this is what I did.
Let's say that I have this entity:
public entity{
int id;
String field1;
String field2;
...
Then I created as many requests as many fields I have to update (not all fields can be updated, such as the ID)
public field1UpdateRequest{
field1 newvalue;
}
and the same for field 2.
These updated are handled using a PUT request, when such a request arrives, it is handled by something like this:
HTTP → Controller→ Service → (DAOS etc.)
So in the controller class I have a PUT http://...//updatefield1 method that accepts field1UpdateRequest objects.
My question is:
Is this right to do? How can I explain that this is right (if it is)? should these requests be PATCH more than PUT? Should a generic PUT request also be included? (Even if I'm scared that this will make the event sourcing part more difficult)?
In a CQRS spproach, it's important to remember that the C stands for Command. Every request to your "write-side" is thus a command. A generic "here is the new value for this resource" request (which is what REST tends to lead to) can be interpreted as a "use this value henceforth" command, but it is a bit of an impedance mismatch with CQRS, because it's a fairly anemic command. There are definitely cases where having that in an API can be called for (and if it's an exceptionally rare request, you may even be able to get away with modeling it as a single "new beginning" event rather than teasing out finer-grained events; this has the cost of shifting some complexity out to consumers of the events).
With that in mind, an alternative approach that updates parts of an object is a little more of a fit with CQRS (though in this case, you are shifting some complexity to requestor, at least if that requestor wants to do wholesale updates). HTTP PUTsounds proper to me: the command is "use this value for this field/component of the entity".
That said, an even more CQRSy API would instead focus on the higher-level activities which motivate a change to the entity. For instance if you're tracking the current owner of the artwork as of when it was sold, you might have a currentOwner and a currentOwnerAcquired field in your artwork entity. When recording a sale, you would want to update both, so a POST /artworks/{artworkId}/transferOwnership endpoint taking something like
{
"transferor": "Joe Bloggs",
"transferee": "Jack Schmoe",
"date": "2021-12-24T00:00:01Z"
}
would allow the update to be a single transaction and allow you to encode the "why" as well as the "what" in your events (which is an advantage of event sourcing).
So in the controller class i have a PUT http://...//updatefield1 method that accepts field1UpdateRequest objects.
Is this right to do?
It might be, but it probably isn't.
Here's the key idea: your REST API is a facade; it supports the illusion that your server is stores and produces documents. In other words, your providing an interface to your data that makes it look like every other site on the web.
The good news: when you do that, you get (for free!) the benefits of a bunch of general purpose work that has already been done for you.
But the cost (of these things that you get for free) is that - for everything to "just work", you need to handle the impedance mismatch between HTTP (which is based on an idiom of documents) and your domain model.
So I send to you messages to "edit your documents", and you in turn figure out how to translate those messages into commands for your domain model.
In HTTP, both PUT and PATCH have remote authoring semantics. Both of those messages mean "make your copy of the document look like my copy". They are the flavor of HTTP messages you would use to (for example) edit the title of an HTML document on your web server.
The semantics are fundamentally anemic. My message tells you how I want your copy of the document to look, your server is responsible for figuring out how to achieve that.
And that's fine when you are working with documents, or using documents as a facade in front of a data model. But matching remote authoring requests with a domain model are a lot harder.
(Recommended reading: Greg Young 2010 on task based user interfaces).
In the case of a domain model, you normally want to send to the server a representation of a command message. HTTP really wants you to deal with command messages in one of two ways:
treat the command message as a document/resource of its own, to be stored on the server (the changes to the domain model are a side effect of storing a new command message)
POST the command message to the resource most directly impacted by the change.
(See Fielding, 2009; it is okay to use POST).
In both cases, the HTTP application itself knows nothing about what's going on at the domain level, it is only concerned with the transfer of documents over the network.
HTTP doesn't really place any constraints on your resource model - if you want to publish all of your information in one document, that's fine. If you want to distribute your information across many documents, that's also fine.
So taking a single entity in your domain, and distributing its information across many resources is fine.
BUT: remember caching. HTTP has simple rules for automatically invalidating previously cached responses; separating the resource you use for reading information from the resource that you use for editing information makes caching harder (caution: caching is already one of the two hard problems).
In other words: trade offs.
For a restfull service, does the noun can be omitted and discarded?
Instead of /service/customers/555/orders/111
Can / should I expose: /service/555/111 ?
Is the first option mandatory or are there several options and this is debatable?
It's totally up to you, I think the nice thing about having the nouns is that it helps you see from the URL what the service is trying to achieve.
Also taking into account that under customer you can have something like below and from the URL you can distinguish between order and quote for a customer
/service/customers/555/quote/111
/service/customers/555/order/111
One of the core aspects of REST is that URLs should be treated as opaque entities. A client should never create a URL, just use URLs that have been supplied by the server. Only the server hosting the entities needs to know something about the URL structure.
So use the URL scheme that makes most sense to you when designing the service.
Regarding the options you mentioned:
Omitting the nouns makes it hard to extend your service if e.g. you want to add products, receipts or other entities.
Having the orders below the customers surprises me (but once again, that's up to you designing the service). I'd expect something like /service/customers/555 and /service/orders/1234567.
Anyway, the RESTful customer document returned from the service should contain links to his or her orders and vice versa (plus all other relevant relationships).
To a certain degree, the "rules" for nameing RESTful endpoints should follow the same naming rules that "Clean Code" for example teaches.
Meaning: names should mean something. And they should say what they mean, and mean what they say.
Coming from there: it probably depends on the nature of that service. If you only can "serve" customers - then you could omit the customer part - because that doesn't add (much) meaningful information. But what if you later want to serve other kinds of clients?
In other words: we can't tell you what is right for your application - because that depends on the requirements / goals of your environment.
And worth noting: do not only consider todays requirements. Step back and consider those "future grow paths" that seem most likely. And then make sure that the API you are defining today will work nicely with those future extensions that are most likely to happen.
Instead of /service/customers/555/orders/111
Can / should I expose: /service/555/111 ?
The question is broad but as you use REST paths to define nested information, that has to be as much explicit as required.
If providing long paths in the URL is a problem for you, as alternative provide the contextual information in the body of the request.
I think that the short way /service/555/111 lacks consistency.
Suppose that /service/555/111 correspond to invoke the service for the customer 555 and the order 111.
You know that. But the client of the API doesn't know necessarily what the paths meaning are.
Besides, suppose now that you wish invoke the invoke the same service for the customer 555 but for the year 2018. How do that now ?
Like that :
/service/555/2018 would be error prone as you will have to add a parameter to convey the last path value and service/555/years/2018 will make your API definition inconsistent.
Clarity, simplicity and consistency matters.
According to me usage of noun is not necessary or comes under any standard,but yes it's usage helps your endpoint to be more specific and simple to understand.
So if any nomenclature is making your URL more human readable or easy to understand then that type or URL I usually prefer to create and keep things simple. It also helps your service consumer who understand the functionality of any service partially by name itself.
Please follow https://restfulapi.net/resource-naming/ for the best practices.
For a restfull service, does the noun can be omitted and discarded?
Yes. REST doesn't care what spelling you use for your resource identifiers.
URL shorteners work just fine.
Choices of spelling are dictated by local convention, they are much like variables in that sense.
Ideally, the spellings are independent of the underlying domain and data models, so that you can change the models without changing the api. Jim Webber expressed the idea this way
The web is not your domain, it's a document management system. All the HTTP verbs apply to the document management domain. URIs do NOT map onto domain objects - that violates encapsulation. Work (ex: issuing commands to the domain model) is a side effect of managing resources. In other words, the resources are part of the anti-corruption layer. You should expect to have many many more resources in your integration domain than you do business objects in your business domain.
Resources adapt your domain model for the web
That said, if you are expecting clients to discover URIs in your documentation (rather than by reading them out of well specified hypermedia responses), then its going to be a good idea to use URI spellings that follow a simple conceptual model.
The HATEOAS principle "Clients make state transitions only through actions that are dynamically identified within hypermedia by the server"
Now I have a problem with the word dynamically, though I guess it's the single most important word there.
If I change one of my parameters from say optional to mandatory in the API, I HAVE to fix my client else the request would fail.
In short, all HATEOAS does is give the server side developer extreme liberty to change the API at will, at the cost of all clients using his/her API.
Am I right in saying this, or am I missing something like versioning or maybe some other media-type than JSON which the server has to adopt?
Any time you change a parameter from optional to mandatory in an API, you will break consumers of that API. That it is a REST API that follows HATEOAS principles does not change this in any way. Instead, if you wish to maintain compatibility you should avoid making such changes; ensure that any call made or message sent by a client written against the old API will continue to function as expected.
On the other hand, it is also a good idea to not write clients to expect the set of returned elements to always be identical. They should be able to ignore additional information given by a server if the server chooses to provide it. Again, this is just good API design.
HATEOAS isn't the problem. Excessively rigid API expectations are the problem. HATEOAS is just part of the solution to the problem (as it potentially relieves clients from having to know vast amounts about the state model of the service, even if it doesn't necessarily make it straight-forward).
Donal Fellows has a good answer, but there's another side to the same coin. The HATEOAS principle doesn't have anything to say itself about the format of your messages (other parts of REST do); instead, it means essentially that the client should not try to know which URI's to act upon out of band. Instead, the server should tell the client which URI's are of interest via hyperlinks (or forms/templates which construct hyperlinks). How it works:
The client starts at state 0.
The client requests a well-known resource.
The server's response moves the client to a new state N. There may be multiple states achievable at this point depending on the response code and payload.
The response includes links (or forms/templates) which tell the client, in band, the set of potential next states.
The client selects one of the potential next states by issuing a method on a URI.
Repeat 3 through 5 to states N+1 and beyond until the client's application needs are met.
In this fashion, the server is free to change the URI that moves the client from state N to state N+1 without breaking the client.
It seems to me that you misunderstood the quoted principle. Your question suggests that you think about the resources and that they could be "dynamically" defined. Like a mandatory property added to certain resource type at the application runtime. This is not what the principle says and this was correctly pointed out in other answers. The quoted principle says that the actions within the hypermedia should be dynamically identified.
The actions available for a given resource may change in time (e.g. because someone added/removed a relationship in the meantime) and there may be different actions available for the same resource but for different users (e.g. because users have different authorization levels). The idea of HATEOAS is that clients should not have any assumptions about actions available for certain resource at any given time. The client should identify available actions each time it reads that resource.
Edit: The below paragraph may be wrong. See the comments for discussion about it.
On the other hand clients may have expectation for the data available in the resource. Like that a book resource must have a title and that it there may be links to the book's author or authors. There is no way of avoiding the coupling introduced by these assumptions but both service providers and clients should use backward-compatibility and versioning techniques to deal with it.
I was wondering whether the use of a decorator pattern is good in case I want my model ("M part" of MVC) to raise Exceptions depending on their origin. I explain myself.
I have a class called Game which is a part of the Model. I have two Views : a GUI and a command line. I want my model to raise an Exception for command line view when the user enters a character instead of a number (for example). Of course I don't want this Exception to be handled by the model as it "belongs" to the command line and not to the Model itself.
To encapsulate those two different behaviors, I plan to decorate the Game class with two classes : CommandLineGame and GUIGame which have only one attribute : Game and handle their own kind of Exception. Is it a good idea ? Is there a better one ? The problem of such a solution is that every model class raising Exception depending on its origin has to be decorated...
What you are describing in the example is "input validation". Strictly speaking*, this belongs in the Controller ("C Part") of MVC.
The separation of concerns for MVC decomposes as follows:
View is there to 1) present a UI for the user to evaluate the state of the program (Also, what your program looks like visually) and 2) to receive the user's expression of intent (receive raw instructions on what they may want to do)
Controller is the actual interpreter of these "actions" or "intentions" from the user. It decides what it means for a user to click a particular button and what to call in your model. It decides whether a particular input actually makes sense given context from the UI (and in some case from the model).
Model should be View/Controller agnostic (Meaning the model should have no knowledge of the View/Controller). It should only be about the internal representation of what you are trying to "model". The advantage of doing it this way: you can have many different UIs, or change your existing UIs without affecting the model.
Overall, the idea is to lower coupling and increase cohesion.
I hope that makes sense =)
Depending on the language / framework, the lines between MVC components get blurred a bit. Some idioms will lump most of Controller into the View, but the encapsulation of logic should stay relatively similar.
*In practice, for defensive programming, input validation is done twice for mutual suspicion: they are broken down into client-side mediation and server-side mediation:
In this case, the Model part should handle the "server-side" mediation: it should check that the arguments passed to its functions actually make sense before proceeding.
Similarly, the Controller/View part should check the input as part of "client-side" mediation, so that it can warn the user right away, without passing it back to the model, and then eventually back to the view.
It will keep your code very clean, something i like a lot from an academic perspective.
On the other hand do you need to introduce this kind of design complexity for a simple problem like this?
So, if you need the code to be clean... GO for it.
I'm trying to use the MVC design pattern for my project but I'm sort of unsure about how to decouple my program into the classes. The first part of my program is a Login screen which requires the user to enter a their username and password and a start button which checks the details, and there is a button to go to a page where you can add a new user. So I was thinking for my MVC design:
loginpanelView : Just the GUI with the text boxes, labels, buttons etc
loginpanelController:
- implement the actionlistener for the start button here and have a reference to the method checkLogin
- implement actionlistener for add user button here and have reference to a method which switches the panels
loginModel:
- defines the actual method which checks the login
switchpanelModel:
- defines a method which creates a cardlayout system and switches the panels
My understanding is that the controller just makes very general references to what needs to be done i.e. sort of what the user wants to happen, then the model defines the exact method of how to handle this? Would someone mind verifying/ correcting my understanding please? I've read a lot about this design pattern but unfortunately I still don't feel like I have a clear understanding of it. Any help would be much appreciated!
p.s. Sorry! I forgot to include that I'm programming in Java
It sometimes helps to think of MVC in terms of dependencies.
The model repesents what your application does. It has no dependencies on anything. It is what makes your application unique.
The view displays information to the user. This information comes from the model. Therefore, the view has a dependency on the model.
The controller's function is to accept input from the user, dispatch that request to the appropriate model functionality, and (normally) accept the return value and supply it for a view to render. Thus, the controller is usually very tightly coupled to the view(s) that it serves. It also has dependencies on the model.
In this case, the model is your authentication scheme. (In reality, this is not all that much of a model but an entry point in your application, your overall model is something like "process payments", "generate report", "request to create widget", etc.)
You have two views, one to enter authentication information and a second for when an authentication succeeds. The first really does not have any model information, it is solely to collect input (however its design will be based on whatever the authentication model needs, so there is still a dependency here). The second will undoubtedly display a list of available features your application offers or display a landing page etc.
It is the controller's responsibility to mediate these interactions. Therefore, information sent from the first view is received by the controller, dispatched to the authentication model, authentication succeeds or fails, and then the controller chooses the appropriate view to render based on the result.
With such a basic "functional design" it's hard to help you exactly, but you might want to think more about the big picture about what you want.
A user model - database model for a user. Contains a "check login"
method
A login-page View - Form, layout etc
A login controller - Gets the stuff out of the form, tries to log someone in with the method from the user object, and create said user
object
The page view/controllers can be split up ofcourse in several sub-parts, but this might not be a bad place to start.
It seems to me that LoginModel and SwitchPaneModel are not models at all. Model is what you store somewhere. So you will have UserModel and PaneModel. And your controller will implement switchPane method and login method. It's good idea to decouple this method in some separate classes there are lots of methods to perform this task. But I strongly recommend you to find ready solution. Don't invent the bicycle.
A good place to start is here. This is a special case of MVC called Passive View. The first important idea is that the view and the model do not communicate with each other at all. The view only tells the controller about events, and the controller manipulates both the view and the model. A controller can even create new controllers and views (such as for complex modal dialogs). And finally, the model does not communicate with anyone!
So you have the right idea: your loginpanelController listens for button events from the loginpanelView, and then calls the right methods in the model to set the data and validate it.
I think one place you may be having a problem with is switchpanelModel. I don't think you need this. If your loginpanelView is the view with the cards in it, then your loginpanelController should be the one switching the cards.
I think models should be restricted to methods working with its own data, but must have no reference to any GUI element anywhere. Models do not drive the program; controllers do.
Rather then thinking in terms of 'defining' a method, perhaps it is better to think in terms of what is being encapsulated.
For example, loosely, in MVC a view encapsulates primarily the user interface of your program (a login form), a model encapsulates some part of your domain logic (password authentication) and a controller encapsulates the logic that connects a view with a model (it depends there are variation of MVC architecture). The controller is often to some extent coupled to a view (especially if you start adding overtly specific ActionListeners etc) however the model should be quite reusable/exchangable (changing how you validate should not mean you have to change any view/controller that uses it)