0

I am creating a API to create Personnels of X city. Assume that there is a generalised service for creating personnel of any city and I want to call this service for X city personnels from my API.

While implementing my API, I am planning to do following:

  1. Validate the input parameters and business logic validation which is specific to X city personnels.
  2. If Validation of the input parameters fails, API will throw 400 with error message
  3. Call the Generic Personnel Service with the input and create the Personnel.
  4. If call passes, create the entry in my datastore for this personnel. And return 200.
  5. If call fails, create the entry in my datastore for this personnel with the error message. And return 400 with the error message.

Following are my doubts in above flow:

  1. In Point 5 that whether it is a good design/pattern to store the failure in datastore or not. One of the reason to store it is to show the users these failures later and so that they know it failed because of this reason.
  2. What type of service my service will be called? Is there any design pattern that this kind of service should follow?
  3. Should I be storing the entity for personnels created by my service at my end or not?

4 Answers 4

2

Don’t think about how you should react to some event, think about how your application will proceed. The end effect is that you wanted to create a new entry in the database for an employee and it failed.

So what happens to this employer? Do they not get paid? Do they not get a pass to enter The building? Is their car not allowed on the parking space? If this is a genuine employee you need to make sure something happens to fix this.

1
  • I don't completely agree. "[...] think about how your application will proceed." means to break encapsulation, will end up with an implementation that's only correct if its callers behave the way you are currently expecting, and that will break in the future if usage patterns change. Jun 3, 2020 at 13:55
0

In general, bad user behavior should not get written to the database - certainly not the same one your data lives in.

Why? Let’s say I am someone who wants to do your service harm. I maybe don’t have a login, but I can spam your service with unauthenticated requests. If that takes longer than your normal path (because you’re making new rows rather than just reading them; because the bad paths are optimized worse/are less cache friendly), the load on your service will suddenly spike. If you log those failures to your database, it’s a quick and easy way for me to fill your database with garbage.

1
  • Thanks for the reply, But that is something I am thinking to avoid by Point 1 where I will do validation of the input parameters and do authz/authn checks. In this Point 1, I won't write to database. Also, are there no cases where it can be useful to store the failures?
    – hatella2
    Jun 2, 2020 at 5:07
0

Your API call is "create personnel", and so I completely agree with your return values (200 in case everything was fine, 400 in case of errors).

But in point 5, I'd not create a personnel entry in the datastore, as that would contradict the answer you're giving to your caller, being "400 - the request failed" Your caller assumes that personnel has not been created although you silently did so.

And that can have serious consequences. Your caller received the failure notice, will probably correct the inconsistencies and retry the "create personnel call". If you don't handle that specifically, you'll end up with two entries, one of them having just historical relevance.

You should be very clear about the situations when its acceptable to create a datastore entry and when not, and to signal success to your caller if and only if you created one.

If you have some appropriate logging system, you can log failed attempts there (and even successful ones if you want).

0

I think you should also think about how your flow works here:

3. Call the Generic Personnel Service with the input and create the Personnel.

4. If call passes, create the entry in my datastore for this personnel. And return 200.

5. If call fails, create the entry in my datastore for this personnel with the error message. And return 400 with the error message.

Along with several other valid points raised above, why would a failure to create the record result in a 'bad request' response? You have already validated the input and returned 400 in point (2).

In this case, I think that this should more readily be a 500 (server error) response - i.e. you have received what you believe to be valid input, attempted to create the record and it failed.

If your validation is correct, then this failure is not down to how the request has been formed, but something beyond the client's control.

(I also would note that one point of failure not considered in the above is a failure to write to the DB)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.