Hot answers tagged

203

Reluctance to modify code for the sake of testing shows that a developer hasn't understood the role of tests, and by implication, their own role in the organization. The software business revolves around delivering a code base that creates business value. We have found, through long and bitter experience, that we cannot create such code bases of nontrivial ...


115

Checking for uniqueness and then setting is an antipattern; it can always happen that the ID is inserted concurrently between checking time and writing time. Databases are equipped to deal with this problem through mechanisms like constraints and transactions; most programming languages aren't. Therefore, if you value data consistency, leave it to the expert ...


75

It's not as simple as you might think. Let's break it down. Writing unit tests is definitely a good thing. BUT! Any change to your code can introduce a bug. So changing the code without a good business reason is not a good idea. Your 'very thin' webapi doesn't seem like the greatest case for unit testing. Changing code and tests at the same time is a bad ...


75

For long-running operations, it often helps to model the active job as a REST resource with its own structure and/or sub-resources. For example, starting a job may return a result such as 202 Accepted Location: https://example.com/jobs/123 At that URL, the client will get a structure such as { "status":"running" } as long as the job ...


61

Those two technologies have a very different purpose. REST is for ordinary calls to an API, with client being an active actor of the exchange. When the client needs to find GPS coordinates of an address, the client initiates the call to the API and waits until it receives the coordinates, or a error occurs, or a timeout elapses. Web sockets are for ...


59

It depends on whether knowing the validity of some input for a task that you aren't permitted to do is a security leak. If it is, you really should to do it the other way round. The only safe response to an unauthorised user is "access denied". If sometimes the response is "bad request" and other times "access denied", you are sending information to an ...


47

A PATCH request can be idempotent, but it isn't required to be. That is the reason it is characterized as non-idempotent. Whether PATCH can be idempotent or not depends strongly on how the required changes are communicated. For example, if the patch format is in the form of {change: 'Name' from: 'benjamin franklin' to: 'john doe'}, then any PATCH request ...


46

Great question! I'm always looking for a better way to structure my projects.. Each point you raise has merit and having explored a variety of solution structures I have to say that I agree the majority of the comments here: there is no perfect solution. A few things to ask yourself when faced with this kind of problem: How complex is this application? ...


46

In your latter scheme, you keep verbs in the URLs of your resources. This should be avoided as the HTTP verbs should be used for that purpose. Embrace the underlying protocol instead of ignoring, duplicating or overriding it. Just look at DELETE /item/delete/:id, you place the same information twice in the same request. This is superfluous and should be ...


39

I think what you call “fail fast” and what I call it is not the same. Telling the database to make a change and handling the failure, that is fast. Your way is complicated, slow and not particularly reliable. That technique of yours is not fail fast, it is “preflighting”. There are sometimes good reasons, but not when you use a database.


32

If you allow a client to access the database directly - which they would do, even with a database abstraction layer, then: You get a coupling between their code and yours - particularly, there is a very strong coupling between your database structure and their code; Your client may do some pretty undesirable stuff on your database - whether it be updating ...


32

TLDR; Remove null properties The first thing to bear in mind is that applications at their edges are not object-oriented (nor functional if programming in that paradigm). The JSON that you receive is not an object and should not be treated as such. It's just structured data which may (or may not) convert into an object. In general, no incoming JSON should ...


27

You are right, there is no clear benefit to introduce a REST API layer between a web app and a database, and it has a cost in complexity and performance overhead. The reason you are getting contradictory answers is confusion about what is the 'client' in your architecture. In your architecture (if I understand it correct), you have browsers interacting ...


25

Well, there are multiple types of validation: Cheap basic sanity-checking, which verifies that the request is not obviously malformed. This is typically at least partially duplicated client-side, to avoid futile round-trips. Anyway, it should be done before access-control to make things easier and less error-prone, as it doesn't risk any information-leak. ...


23

SOAP, REST AND PEOPLE'S CREATIVITY SOAP needs a description document like WSDL because each resource can be consumed with different messages, there are no definition on the protocol about constraints to the possible names/messages that you can manipulate a resource. For example, in SOAP your web service that allow clients manipulate an user can expose the ...


21

Is CQRS a relatively complicated and costly pattern ? Yes. Is it over-engineering ? Absolutely not. In the original article where Martin Fowler talks about CQRS you can see a lot of warnings about not using CQRS where it's not applicable: Like any pattern, CQRS is useful in some places, but not in others. CQRS is a significant mental leap for all concerned, ...


21

The most direct quote I've found is part of Scott Guthrie's announcement of the MVC 4 roadmap, back in 2012, (apparently offline but available via the Wayback Machine) which contains the following quote: Json.NET: We plan to use the community developed Json.NET serialization stack in our default JSON formatter in ASP.NET Web API. Json.NET provides the ...


20

Given that: The two "big name" implementors, Netflix and Ebay, abandoned it a couple of years ago and excitement for OData pretty much died with their departure, OData is a RESTful way of exposing a query mechanism through an abstraction layer. Such abstractions are now widely seen as leaky abstractions, which are a clear anti-pattern, I'd suggest OData is ...


19

You can use anything as JSON keys, as long as it is valid UTF-8, doesn't contain zero code points, and it would be useful if you could represent the key as a string in the programming language of your choice. I might recommend not to use different Unicode representations of the same string (for example "Ä" written as one or two code points). Reading some ...


18

Going with an empty string is a definitive no. Empty string still is a value, it is just empty. No value should be indicated using a construct which represents nothing, null. From API developer's point of view, there exist only two types of properties: required (these MUST have a value of their specific type and MUST NOT ever be empty), optional (these MAY ...


18

Designing code to be inherently testable is not a code smell; on the contrary, it is the sign of a good design. There are several well-known and widely-used design patterns based on this (e.g., Model-View-Presenter) that offer easy (easier) testing as a big advantage. So, if you need to write an interface for your concrete class in order to more easily test ...


17

Its not a brilliant idea. The URI is not really a good place for data of unpredictable length, and although there is no 'official' maximum length, many webservers apply their own limit (IIS is 2083 characters, for example). Some webservers also have restrictions on acceptable characters in URIs. There are also other considerations that are generic to URIs. ...


16

PATCH requests describe a set of operations to be applied to a resource, if you apply the same set of operations twice to the same resource, the result may not be the same. This is because defining the operations is up to you. In other words you have to define the merging rules. Remember a PATCH request could be used for patching resources in many different ...


16

This started as a comment but grew too large. No, as the other answers have stated, this pattern should not be used.* When dealing with systems that use asynchronous components, there will always be a race condition where the database (or file system, or other async system) may change between the check and the change. A check of this type is simply not a ...


15

The first one. A URI/URL is a resource identifier (hint in the name: uniform resource identifier). With the first convention, the resource being talked about when you do "GET /user/123" and the resource being talked about when you do "DELETE /user/123" is clearly the same resource because they have the same URL. With the second convention, you cannot be ...


15

You should architect the API around resources, not around roles, e.g.: /rest/students should be accessible to anyone with a role that allows them to see students. Internally, you are implementing role-based security. How you go about that depends on the details of your application, but let's say you have a role table, each person has one or more roles, ...


15

I have a REST API with GETs operations which receive a (long) list of > parameters. Which is the best practice to manage this scenario? AFAIK, there is no firmly established best practice (sorry). However, one can make some recommendations: Try to avoid using POST (instead of GET) if the request is safe (i.e. side-effect free, in particular not modifying ...


14

I know it may seem like you are converting objects back and forth all the time between your database objects, your data transfer objects, your client objects with validation logic and so on but I'd say that no, you're not doing anything wrong. Each of these objects may represent the same unit of information, but they have very different responsibilities. ...


14

I think clear answer when PATCH in not idempotent is this paragraph from RFC 5789: There are also cases where patch formats do not need to operate from a known base-point (e.g., appending text lines to log files, or non- colliding rows to database tables), in which case the same care in client requests is not needed. As RFC specifies that patch ...


14

Warning: big post, some opinions, vague 'do what works best for you' conclusion Generally, this is done as a means of implementing 'hexagonal architecture' around your database. You can have web applications, mobile applications, desktop applications, bulk importers, and background processing all consume your database in a uniform way. Certainly you could ...


Only top voted, non community-wiki answers of a minimum length are eligible