I have this scenario in my 3-tier app with a Service Layer that serves to a MVC presentation layer:
I have an operation that creates, for example, an Employee whose email must be unique in the set of Employees. This operation is executed in the MVC presentation layer through a service.
How do I manage the intent to create a Employee whose email is already registered in the Database for another Employee?
I am thinking in 2 options:
1) Have another operation that queries if there's an Employee with the same email given for the new Employee.
2) Throw an exception in the service CreateEmployee for the duplicate email.
I think it is a matter of what I think is best or most suitable for the problem.
I propose the 1) option because I think that this is a matter of validation.
But the 2) option only needs 1 call to the service, therefore its (?) more efficient.
What do you think?
Thanks!
I would definitely go with second option:
as you mentioned it avoids 1 call to the service
it keeps your service interface clean with just one method for the employee creation
it is consistant from a transactional point of view (an exception meaning "transaction failed"). Keep in mind that validation is not only one of the many reasons that can make the transaction fail.
imagine your validation constraints evolve (ex: other employee attributes...), you won't want to make all you implementation evolve only for this.
Something to have in mind: Make sure to make your Exception verbose enough to identify clearly the cause of the failure.
If by 'Presentation' layer you really mean presentation, you should not be creating a new employee in that layer. You should only be preparing any data to be cleanly presented in the HTTP response object.
Generally a good way to think of this sort of problem is to consider what your service objects should do if called by a command-line program:
> createEmployee allison.brie#awesome.com
Error! 'allison.brie#awesome.com' is already registered.
In this there is some terminal management layer that calls the service. The service does something to realize there is another user with the same email, and throws an appropriate exception (ie DuplicateUserException). Then the terminal management layer interprets that exception and prints out "Error! " + exception.getMessage();
That said, note that your two options are actually the same option. Your service must still query the database for the duplicate. While this is 'validation' it is not input validation. Input validation means checking to see if it's a valid email address. (Is there an '#' symbol and a valid TLD?)
Related
I have a collection of documents that need to be processed by multiple client nodes.
Basically, each document should be processed by only 1 client node.
So what I'm thinking of is creating a unique clientId for each node and set the clientId to the document being processed to tell other clients that this document is being processed.
I already implemented this approach using Mongodb a couple of years ago by using the findAndModify operator which guarantees the atomicity of both setting the clientId to the document and returning it.
Now I'm looking for a maybe similar approach in Couchbase but couldn't find.
Any idea on how to do it?
I think what you are searching for is the method called getAndLock. It will guarantee that only one server is reading this document.
Updating the document with an attribute might be a bad idea if the server fails during this process, as no other server will take over those documents that have already have been assigned to the faulty one.
We have handeled similar kind of scenario in our project. What we do is to create one document and save other processing doc in that. If that document is not present in that, then it you can prevent it getting updated by other client.
For the development of an API we want to create a new organization and a new user for that organization with one form submission (the registration) using a clean RESTful API design.
As we don't want to mix different resources (organizations and users) and create the them with one call (the response of that call is it an organization or an user?) we need to split the registration into two calls: create organization first and directly after create user.
But if the user and organization creation is split into two independent API calls we see the following problems:
How to handle errors? Eg. if the create organization is successful but the create user fails due to an error (eg. user email already exists). In that case an organization without any user is created and nobody can login to change the organization resource.
How to handle the authorization after creating the organization? Can everybody with the organization id simply create a new user without any login check (login is only possible with email and password)? Or will the create organization return a token to create the first user? (The token logic will make the client quite complicated: how to handle resubmissions etc.)
How to handle errors? Eg. if the create organization is successful but the create user fails due to an error (eg. user email already exists). In that case an organization without any user is created and nobody can login to change the organization resource
Except for PATCH none of the standard HTTP methods really tackles a transactional behavior. PATCH i.e. demands that all of the instruction steps defined within the patch document need to be processed atomically. Either all or none of them have to be applied. So if one instruction fails none of the modifications must be applied. The difference between PATCH and the other methods however is, that PATCH should contain a set of instructions to apply onto one or multiple resources while the other operation in a sense target a single document usually.
If viewed from a document management system, which HTTP truely is at its heart as any business rules you conclude are just a side-effect of the document management (see this great talk), the operations of HTTP make a bit more sense. I.e. PUT replaces the current document with the one provided. If none existed so far it is similar to a document creation. The spec here mentions that PUT is allowed to have side-effects. I.e. similar to GIT where a commit will push the head forward though the actual commit will still be accessible via its own URI. DELETE removes the association of the URI to the document stored. Whether that leads to a document removal on the imaginary filesystem or not is an implementation detail. GET will only return the content of that document to the invoker and POST only processes the request according to the service own semantics giving no further promises on what it does with the payload. So whether one or multiple resources are created, or even none at all, is up to the implementation. However, if you create resources you need to return a 201 Created response containing a Location header with the URI of the newly created resource that hints clients about the newly created resource. In the case of multiple resources being created, the spec is a bit less clear what should be returned in that case as only one Location header may appear within the respone.
The usage of a form-based creation approach is for sure a RESTful approach as here the server teaches a client on the needed inputs to perform the task. A client usually isn't that much interested in how the server is actually processing and storing the data, all it is interested in is the completion of its request, either successfully or with a hint on the problems the server had while processing the request.
Whether you create everything in one go or divide each part to its own request is some choice you have to make. I.e. on a typical Web site you may encounter a wizzard like approach were you enter some organization related information first into a form, click a submit button and then get a further form response asking you to enter user details with a further response summarizing the details and asking for confirmation. The data could be stored in some temporary resource that on confirming the summary will create everything in one go mimicking some kind of atomic processing failing the creation of the organization in case some problems were encountered with the user details and such. Such an approach is convenient if you have multiple optional data that depends on previous choices.
Of course you could also enter the data in one single form and send it to the server via a POST request and then create the respective resources that way. Which URL to return in the Location header is yet a different decision. If the main resource being created is the organization that I'd opt for the organization URI, especially if it allows to list its defined users. Internally you can utilize transactions to guarantee a consistent state between organization and user and in a failure to do this you simply can roll back the transaction and return an error to the user.
If you attempt to divide the creation into multiple steps you surely will have to deal with the exception case of the user resources and its effects on the organization resource. As mentioned HTTP does not give any hints on that as to HTTP these are two separate and unrelated requests. Here, not the server should be the smart thing but the client has to be. If it encounters problems while user creation it should perform the cleanup of the organization itself. The server/API is just seen as dumb storage thing in such a case.
How to handle the authorization after creating the organization? Can everybody with the organization id simply create a new user without any login check (login is only possible with email and password)? Or will the create organization return a token to create the first user? (The token logic will make the client quite complicated: how to handle resubmissions etc.)
It basically depends on your design here. Usually some kind of permission management should be added to the API. Some frameworks already contain support for such, i.e. in the Java and Spring ecosystem you can add certain annotations onto operation endpoints and business methods that check certain assigned user roles and permissions and only allow access if they are available.
In case you have a split organization and user creation approach and encountered a problem during user creation you could send a form back to the client requesting other user details as one already exist for an other organization until valid data was returned. Plenty of Web-based APIs nowadys send some confirmation links via mail to verify the correctness of the email-address and the user is only "logged-in" the first time when he clicked the activation link in that email. In pure HTTP you'd send a HTTP Authorization header containing the user credentials. In the absence of an activated user the service would return 401 Unauthorized as failure preventing the user from authenticating with the service. In such a case an external administrative entity (i.e. a project manager or administrator of the API) would have to create a user for that organization and send the data to the requestor. Though, such a state should be highly avoided IMO. Here, probing a user for admissible user details is sure preferrable, I guess.
You might also run some kind of cleanup routine in the back (or perform a manual cleanup task) after a given threshold amount on organizations that have no user assigned to it to free up resources and avoid carrying arround inconsitent state, according to your definition, as there has to be a user assigned to an organization.
As you see, you have a couple of design choices how to tackle such a scenario. Whether you enter the data in one form and send everything in one go to the server or use a temporary resource to collect data from n consecutive form requests until the user confirms that data and you process everything in one go atomically or you use dedicated requests per task and have some backing routines that check the consitency of the system is up to you.
A final note on a thing mentioned in your title. REST clients shouldn't consider resources to have a specific type as this leads to clients expecting certain endpoints to return certain types. This also leads to clients interpreting URIs to determine the type of that resource. As the server is free to change its URI scheme any time it wants to, chances are that clients wont be able to determine the type based on the URI automatically without a developer building in that kind of knowledge into the client. This avoids the actual benefits a REST architecture should provide, namely the freedom for evolution in future that is enabled by the decoupling of clients from servers. Instead of using typed resources clients should rely on content-type negotiation where standardized representation formats understood and supported by both, client and server, are exchanged. The media-types defining these representation formats specify the processing rules and semantics of each of the elements within the payload and allow interoperability.
This should be a pretty common issue: let's say I'm updating a users table as well as a users_organizations table. From the UI perspective, there is only one button "Save".
I can either:
1) Create a single API route
2) Create one API route for each resource (one for users, one for users_organizations)
And then, suppose I choose 1). Should I update both tables in a single database call or should I split it up into 2 database calls?
In general I'm never sure how to approach these problems. Sometimes there's an action that affects more than 2 database tables at once. How do I ensure robustness, proper error handling, and keep my code sane all at once?
Definitely a problem I struggle with as well.
From what I've seen in the past, most operations that go along with a UI action are related, and can be given a common action name like update-user when clicking "Save". I'd have a single API endpoint to update the user, such as PUT /api/users/123 in a REST API. The body of that request would contain updated fields and new organizations the user belongs to.
Then on the server side I would make 2 database calls, one to update the user table and one to update the user_organization table.
If you feel 2 operations are so different that it's difficult to come up with a common API endpoint name, or if they need to be called independently in other parts of the app, I would argue that they should be 2 different API endpoints.
At the end of the day I try to ask, if a new developer were to try to understand this code, what would be the simplest approach?
I am writing a web application using JSP, with a mysql database that keeps track of all the users. In a web page I use a form to allow users to register.
In my database, for example the username of an user has a maximum of 20 characters, so I would avoid to allow an user to register with an username longer than 20. In my application I am strictly separating all levels, so there's a strong separation between services, business logics, business flows and the presentation level done with JSP pages.
My concern is about where I should check that any given field is correct. In business logics I implement a class that abstracts the concept of an user, allowing to create a new user and inserting it in my database. In business flows (that is beans) I can elaborate all the HTTP parameters received, so I know all the fields values. I could do it in my JSP page, even with javascript analyzing every inserted field and conditionally submitting the form, in beans or in my "user" class. Which one would be the most correct?
Assuming you're using a pattern close to MVC
The input validation is relevant to the controller part. It's up to your controller to process data, then display user friendly error message by passing these errors message to your view.
Any processing have to be done in the controller and validating data is processing.
Anyway, an extra security on model isn't a bad thing, but in this case it's totally useless because you database engine will truncate (or throw an error) if you're inserting more than 20 characters, so security is allready in place.
Models are only meant to acces and store data, not validate it! (Except some rare case when data storage need validation and when database structure don't check integrity by itself).
But again, these are just concepts, you're free to adopt concepts in the way you like. As long as you're consistent across your application (don't do some validations in models, some in controllers, and why not some in view if we are at that!)
I would do it in the model class.
What you must not do is doong the validation with javascript in the client, because the user can disable JS
When running some code Meteor throws a throwIfSelectorIsNotId exception. I have two clients running the same code and the exception is thrown when the second client is running the same pice of code.
Cant figure out what this exception means and why it is thrown. Hopefully someone will be able to explain it.
For certain operations on the client (since version 0.57 I think it was). When doing an update operation e.g
MyCollection.update({name:"John Doe"},{$set:{age:50}});
You need to split it into two parts, on the client. (Only on the client).
var doc_id = MyCollection.findOne({name:"John Doe"})._id;
MyCollection.update({_id:doc_id,{$set:{age:50}});
You need to find the document by the _id first then update that document. The selector can only be an _id for update & remove operations.
This is because of a security risk with meteor's design, if there were to be a client side mongodb database it could arbitrarily get information from the server on other operations while determining on whether to allow the update or not. It was introduced in Meteor 0.57.