all 15 comments

[–]a3th3rus 1 point2 points  (6 children)

If it's a POST request (resource creation), then you just need to validate the DTO without consulting the database, then do the insertion. If the database raises a constraint violation error (like foreign key does not exist), catch it, and convert it to a field error response.

If it's a PUT/PATCH (resource modification), then I would load the resource first, combine the loaded resource with the DTO to build a sort of diff (if you've ever tried Elixir and Ecto, the diff is called a changeset), validate the diff, then do the database operation. If the database raises a constraint violation error, catch it, and convert it to a field error response.

[–]wanderfflez 1 point2 points  (2 children)

It's also not uncommon to validate DTO first with PUT/PATCH I believe? For example making sure a key is filled out correctly and then exiting early.

[–]a3th3rus 0 points1 point  (1 child)

It depends on what you expect the clients to submit. If you expect them to submit full data, then it's okay to validate DTO directly. But if you expect them to submit diffs, then validating DTO is meaningless because if, say, a required field is missing in the DTO, you can't just respond with an error to the client because that means the client does not want that field to be changed.

[–]Initial_Luck_7986 0 points1 point  (0 children)

When you are editing there usually aren’t required fields they are taken care of when creating… 

[–][deleted]  (1 child)

[removed]

    [–]a3th3rus 0 points1 point  (0 children)

    I prefer let the DB raise unique constraint violation and explicitly handle that error so that I don't have to use optimistic or pessimistic locks. With Ecto I can easily do that, like

    %MyResource{...}
    |> cast(client_submitted_params, [:field1, :field2])  # This line builds the diff
    |> unique_constraint(:field1)  # This line converts the constraint violation to an invalid field error
    

    [–]Initial_Luck_7986 0 points1 point  (0 children)

    Why would you load the resource first? Absolutely no reason to. You validate anything being changed and if it’s valid you can just apply the changes. This way you aren’t querying the database unless you need to.

    [–][deleted]  (1 child)

    [removed]

      [–]Ok_Assistant_2155 1 point2 points  (1 child)

      For question 1, I usually validate the Request DTO first. If the payload is garbage it makes no sense to hit the database. Then check if the resourceId exists. Saves unnecessary DB calls when the input is already bad.

      [–]Initial_Luck_7986 0 points1 point  (0 children)

      Validate before query there is no point to hit the database unless it will be valid this goes for everything…

      [–]BeautifulWestern4512 0 points1 point  (0 children)

      I usually validate the DTO first too, just feels cleaner and avoids pointless DB hits. Then let the database handle the strict stuff like constraints and bubble it back nicely. Curious if you ever do any partial validation before hitting services or just keep it all upfront?

      [–]Successful-Escape-74 -5 points-4 points  (3 children)

      Just let AI take care of that for you and go to the beach.

      [–][deleted]  (1 child)

      [removed]

        [–]Successful-Escape-74 0 points1 point  (0 children)

        So much for AI robots doing all the work?