Тёмный

How to (and how not to) design REST APIs 

CodeOpinion
Подписаться 84 тыс.
Просмотров 48 тыс.
50% 1

Everyone seems to love best practices or rules around how to design REST APIs. But is all this guidance good advice? Well, let's find out.
🔗 EventStoreDB
eventsto.re/codeopinion
🔔 Subscribe: / @codeopinion
💥 Join this channel to get access to a private Discord Server and any source code in my videos.
🔥 Join via Patreon
/ codeopinion
✔️ Join via RU-vid
/ @codeopinion
📝 Blog: codeopinion.com
👋 Twitter: / codeopinion
✨ LinkedIn: / dcomartin
📧 Weekly Updates: mailchi.mp/63c7a0b3ff38/codeo...
Original Post
github.com/stickfigure/blog/w...

Наука

Опубликовано:

 

4 дек 2023

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 115   
@CodeOpinion
@CodeOpinion 6 месяцев назад
Learn more about Software Architecture & Design by subscribing to my newsletter. 🚀mailchi.mp/63c7a0b3ff38/codeopinion
@gosnooky
@gosnooky 6 месяцев назад
I fully, 100% disagree with #8. 404 is EXACTLY what you should use if a resource is NOT FOUND. A 410 implies that it was once there, but exists no longer. For that to make sense, you would have to determine if in fact the ID once pointed to a valid record that has since been deleted (or soft-deleted), or if the ID never existed in the first place (such as using the ID "unicorn" instead of the expected numeric string or UUID. To make this semantically correct, the endpoint would have to perform logic to decide whether to return a 404 or 410. The use case I use for 410 Gone is when a record IS still in the database but for some reason should not be returned, such as a dependency on a user account that has been disabled or banned. Please use 404 for missing resources.
@denispalt9184
@denispalt9184 2 дня назад
I can kind of see the use case, of sending a diffrent code than 404. As a User i am Usually correlating a 404 with "typo in url" or " bad url". If your server is unavailable, there is a high chance, that you will get a 404 by a proxy. To differenciate the best practise should be "always return a body with usable in formation on 404" to make error handling easier :)
@denispalt9184
@denispalt9184 2 дня назад
Nevermind, this is somewhat covered by #10
@warvariuc
@warvariuc 6 месяцев назад
6:32 "ids become opaque, you don't care about them, you provide your client with urls". Very often the API client needs the IDs to call other APIs.
@barneylaurance1865
@barneylaurance1865 6 месяцев назад
Then you can provide it with a key like "other_api_id". E.g. "stripe_id" if your client is going to also use the stripe API or something.
@johanneskingma
@johanneskingma 4 месяца назад
...but than.. 7:35 use prefixes? why prefixes when you just said IDs don't matter to the client. This conflicts with Rule #9
@faximori
@faximori 6 месяцев назад
I would add another rule. 422 - as a validation error. Developers tend to use 400 as response which is incorrect. When payload structure is malformed usually your REST Framework will return 400. But when data is incorrect (value above max, invalid length etc.) you should return 422.
@gosnooky
@gosnooky 6 месяцев назад
Agree 100%. People just don't take advantage of the more obscure response codes. This makes it easier for front-end consumers to react to API errors from a semantic perspective.
@uglypie182
@uglypie182 6 месяцев назад
​@@gosnookyissue is that http status codes often doesn't fit with the application domain. It's better in my opinion to use the most common http statuses, and then have some application specific codes or handling for the rest
@allinvanguard
@allinvanguard 6 месяцев назад
#2 is a very good rule in my opinion. I like to stick to the common convention for top level, globally unique items. But it gets very messy once you need multi-layer drilldowns and even expose internal details with a patch. Now your API is coupled to your internal implementation forever. I'd rather use a simple POST with the actual use case and be flexible in how I implement it behind my API contract. #8 is a very confusing take. I feel like all the tooling and expectations around http (e.g. jaeger etc.) are opinionated on having status codes represent application logic. I don't think I've ever seen a 410 in the wild. So I'd absolutely agree with your opinion here. Really love your API design videos lately, I was able to pick up quite a few fresh ideas and it did challenge some of my previous opinions for the better!
@nikogj9495
@nikogj9495 6 месяцев назад
The idempotency key inside the hypermedia is actually very clever ! Though I suspect it might require additional handling on server side
@Computerix
@Computerix 4 месяца назад
Love your content. Been binge watching for a few hours now, very beneficial, keep it up!
@CodeOpinion
@CodeOpinion 4 месяца назад
Glad you enjoy it!
@marna_li
@marna_li 6 месяцев назад
I think that the reasons for many developers picking whatever seems to be common practice is inexperience. Picking common practice is not always best practice. It is highly contextual.
@TheChexmo
@TheChexmo 6 месяцев назад
I'll continue using my 404, I need to program real world software, thanks
@MrBildo
@MrBildo 6 месяцев назад
I can see many sides to these arguments. I have my own preferences, fine. However, #9 is the best rule to follow. Pick a pattern that makes sense to you and BE CONSISTENT. I have some older code where I wasn't consistent and it sucks. It's tech debt.
@joehernandez3231
@joehernandez3231 6 месяцев назад
This had some helpful insight into best practices. On #12, you mentioned that you would provide a link to another video about date/time best practices, but I didn't see that link at the end of the video. Can you provide the link to that?
@CodeOpinion
@CodeOpinion 6 месяцев назад
Yup here it is: ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-Bxf_HMs7SeQ.html
@jenswurm
@jenswurm 6 месяцев назад
8:00 I think the biggest problem of 404 is that it's overused. One cannot rely on 404 to mean that the requested resource positively does not exist. All one knows when getting a 404 is that it's temporarily inaccessible. This results in two problems: * The client cannot rely on the resource genuinely not existing * The monitoring cannot distinguish between 404s that are infrastructure failure (bad proxies), 404s that are business logic failure (inconsistent data) and 404s that are genuine client errors.
@adambickford8720
@adambickford8720 6 месяцев назад
Infra shouldn't be giving 404s, that's what 502/503/etc are for
@jenswurm
@jenswurm 6 месяцев назад
@@adambickford8720 True, but in many environments it happens nonetheless. For example, a misconfigured nginx will return 404 if it does not know what to do with your request. The same happens if an application completely failed to start up or is currently undeployed in a Tomcat or application server and its context path is thus unknown to the server; usually it'll respond with 404 then as well.
@adambickford8720
@adambickford8720 6 месяцев назад
@@jenswurm Then you should fix the root cause, not tweak everyone affected by it.
@jenswurm
@jenswurm 6 месяцев назад
​@@adambickford8720 That root cause is partially written into the HTTP spec, RFC7231 Quote: _"The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists. A 404 status code does not indicate whether this lack of representation is temporary or permanent;"_ So a 404 can occur only temporarily and for multiple reasons, such as an authorization problem (server unwilling to disclose that the resource exists). That's not going to change anytime soon. Things like nginxes returning 404 where 502 would have been better still also is technically compliant with that spec. That misconfigured nginx genuinely has no representation of the requested resource, so 404 isn't wrong there. But let's assume that it may get fixed/improved in a couple of years. What to do until then?
@it_masterz
@it_masterz 6 месяцев назад
Thank you so much for this sharing. Can you please have a php dedicated video for DDD and clean architecture Its really not easy to find a trusted resource for that
@Silky987
@Silky987 6 месяцев назад
I think some of the issues with devs steering away from standards or defined rulesets is because the sheer amount of tutorials/guides avoid actually implementing them so they can get their content out "quickly". I see a lot of, "That's a topic for a different day" or "just for this tutorial" to hint at the viewer that's it is not up to standards, but no link or follow-up to the recommended approach. The 404/410 approach seems weird to me. Never have I ever seen a 410 in any production system I've integrated with. 99% of the time it's a 404 or empty result (I don't like those) or a 400 with a message. I agree with you on all these points, though I've only come across 1 production API that used hypermedia somewhat effectively (vCloud). I think that breaks down with gateway API's or complicates them greatly so it's generally avoided. Great video!
@DiogoBaeder
@DiogoBaeder 5 месяцев назад
One more hint I would give to people developing not only RESTful APIs, but anything that has to work with JSON or heap maps / dictionaries / objects, is to organize dynamic items separately from "structural items". For example, let's say we have a map representing a "car manufacturer". Suppose this map has: "brand_name", "founded_at" and other properties that describe the manufacturer. It would be a bad idea to also put the car names on the same level as these properties, like "picasso", "kombi" etc, describing each car. The reason is because it's terrible to de-serialize this kind of data - it creates problems with strongly typed applications.
@TheChonsey
@TheChonsey 6 месяцев назад
If I could I would send someone to the past to the day when Roy Fielding was defending his Phd thesis and do everything possible and impossible so that all this REST thing never happened. And on the way back would also visit whoever decided to invent a term microservice. I can’t event think and count the amount of time I personally spent arguing and thinking what verb should be used or what the proper URI structure should be. Do whatever solves the problem
@steveofficer9255
@steveofficer9255 6 месяцев назад
REST is a description of the architecture used to design the world wide web. If REST had never happened, then websites wouldnt be able to interlink and browers wouldn't be able to render arbitrary pages. REST is a description of first and foremost hypermedia, well-defined content types, caching and content negotiation
@DiogoBaeder
@DiogoBaeder 5 месяцев назад
Removing IDs from listings is fine, but keeping them is actually useful in some cases. For example, when there's no other way to determine the identity of a certain resource presented in the UI. Having the ID somehow available might be very helpful for investigation/RCA. In multiple occasions I've used IDs available in certain places to filter in logs, to investigate issues.
@AnPham-uz3td
@AnPham-uz3td Месяц назад
if we use plurals then what if the item is "analysis", would it be "analyses" or "analysiss" ? Please give me opinion on items that are irregular plural
@it_masterz
@it_masterz 6 месяцев назад
Can you please make an example of implement DDD for an HR or ERP system I know it’s really needs alot of videos 😅😅but those large systems who we care about when talking about DDD😢😢
@tyo007
@tyo007 6 месяцев назад
what if the href response containing the api url require auth?woudn't the caller needs to know how to authenticate as well (which means service A needs to know something about service B?)
@ZockaRocka
@ZockaRocka 6 месяцев назад
Can you give some insight on GraphQL API's too? Would be awesome!
@dealloc
@dealloc 6 месяцев назад
10:30 Your example is not 1:1. Your example passed an ID from an existing resource, but in the doc it used a POST to create a new resource. While you could put an arbitrary key for idempotency in the URL when creating a resource, it falsely presumes that the idempotency key is part of the resource being created, which is not true. It's the part of the request lifecycle, but not the resource. You could put it in a query parameter, but that is just bikeshedding at this point. I'd argue it's easier to implement general middleware for handling idempotency using headers, than having to potentially parse URLs to extract keys to be used for the same purpose.
@Tony-dp1rl
@Tony-dp1rl 6 месяцев назад
I question the /v3/application/listings/{listing_id} of Rule #2 being "GOOD" too. Putting the version number at the start makes routing and WAF rules more complex. I would prefer /application/v3/.... so I can more easily route/rule application a certain way. I don't even think some popular systems like Azure App Gateway would support the wildcard/pattern needed to match future versions the way it was described, but I could be wrong.
@HrHaakon
@HrHaakon 6 месяцев назад
That's an interesting point. I've never thought about it that way.
@RealDieselMeister
@RealDieselMeister 6 месяцев назад
@@HrHaakon you can put a version number also in a header of the request. The important thing is, that your API is good documented.
@chswin
@chswin 6 месяцев назад
Well said… some of my apps are entity based and fit the noun/property structure and others are just commands and methods.
@semosancus5506
@semosancus5506 6 месяцев назад
I try really hard to avoid RPC type APIs. I find my APIs are easier to use if I somehow convert that RPC into a resource that is requested. It just makes it easier to think about.
@Parthibansekar87
@Parthibansekar87 5 месяцев назад
Absolutely! Return 404 for nonexistent resources! What’s your two cents on Hate oas and versioning?
@darknessgp1
@darknessgp1 6 месяцев назад
While I agree with some points on not blindly following CRUD like standards, I do not like the justification of "well, we give the consumer the URI for what they can do with this object, so we can define it however we want." I love the idea of providing back links, especially to available actions. What I dislike is the idea that that gives anyone free rain to do whatever they want. Take the cancel action, based on the argument that the URI will be provided, why couldn't the route be "/orders/123/4k52l" where "4k52l" is an action code? If they are getting an array of actions with a name, they can easily tell it's for a cancel, but now the URI is just a mess.
@steveofficer9255
@steveofficer9255 6 месяцев назад
I think that is the issue with everything software related. Technically the computer doesnt care what the URI looks like. The HATEOAS/hypermedia approach is the technical design for building autonomous systems that can adapt to topological changes without needing rewritten. The neatness of URIs is a purely human concern and where people feel the need to bike shed. I think the gist of the rules is that focus on the stuff that makes the system work first and foremost. Then be pragmatic about everything else because it is mostly subjective and will change based on who is on the team and what their current perspective on the system design is
@RikThePixel
@RikThePixel 2 месяца назад
What kind of issues do you run into when using hypermedia? (Not an issue, just a question) If I understand it correctly, you'd need to fetch the a resource first before you can perform actions. This makes sense, because you wouldn't be changing a resource without knowing what it is. How would you obtain the initial uri for the resource?
@CodeOpinion
@CodeOpinion 2 месяца назад
Directly linking is problematic. It often forces you traverse via some input/home URI. The more "entry points" you add can lose the ability to evolve them.
@Jacek2048
@Jacek2048 6 месяцев назад
Hypermedia, hypermedia... cool, but how do I make the initial request? My client code has to know the URL structure.
@RealDieselMeister
@RealDieselMeister 6 месяцев назад
in the theory you have a starting URL, where you get all the urls for all the resources your service provide. I do not like this at all. We have things like open api, swagger or what ever. So there is in my opinion no need for this huge overhead. But that's only my opinion on this.
@steveofficer9255
@steveofficer9255 6 месяцев назад
It's not just in theory. How does the browser work when you open it up? You have a starting url and the returned HTML contains links that allow the browser to navigate you all over the web. The original intent was that when you have well defined content types (like HTML) then any client that understands the content schema can autonomously navigate your system state. To me the big problem is that people get stuck on JSON being their content type rather than defining more specialised content types specific to their system. Or working within their industry to define a more standards based content type to help promote interoperability.
@stepanyaki2377
@stepanyaki2377 6 месяцев назад
Thanks for this interesting topic. About rule #4, what about returning an array as root object and using HTTP Content-Range in Response header to indicate the length or if there is more data to fetch ?
@MarekFr
@MarekFr 6 месяцев назад
This is basically what I did in our last big project. I put pagination details into custom X-Something headers. The body is meant for the actual requested data, metadata should always be in the headers imho.
@bobbycrosby9765
@bobbycrosby9765 6 месяцев назад
There are never any rules, only guidelines. I don't return a 404 because production breakages can result in errant 404s. I want 404 to be a full blown, actual error. It's a pragmatic decision. When I get a 404 it means alarm bells are going off. If I used a 404 in everyday rest responses I would need more sophisticated monitoring to detect the problem. That said, I think arguing about http return codes is bikeshedding. Some of the stack overflow questions about this make me laugh - quibbling over if you should return this or that http error code in whichever situation. Http error codes were not designed to be a catch all for every error you might surface in an API. There's never going to be a perfect answer.
@kevinlloyd9507
@kevinlloyd9507 6 месяцев назад
This right here. We used to do 404s but, they honestly caused more problems. Mainly in monitoring. Is it a null resource or is it a poorly constructed URI. Also, on the client end when consuming these, usually the code that cares about the business reason of "this thing doesn't exist" has all the HTTP logic abstracted away. So parsing headers response codes becomes messy. Where is it I return an empty response with a 200. All I do is a simple null check. Now if you have a sophisticated client library that handles stuff like that, then all good. But it felt like a lot of work to go through just to make HTTP standard codes be happy. But at the end of the day, it's about being pragmatic and setting appropriate expectations. For a public API, maybe we would do a 404 because that's what most consumers expect?
@qj0n
@qj0n 6 месяцев назад
I'd say there are at least 3 different levels on which absence of sth might result in 404: 1. There is an endpoint, but supplied id wasn't found in db 2. There is no such endpoint so your framework returned 404 3. The app is down, so the server returned 404
@barneylaurance1865
@barneylaurance1865 6 месяцев назад
@@qj0n Yes, but there is no concept of "endpoint" in HTTP. If endpoints exist they are an internal thing about how the server is built. The client doesn't need to know the distinction between one endpoint and another, especially if they are not constructing URIs. The client also doesn't need to know whether or not you have a database. As far as the client is concerned if they're just doing GET requests for orders your server could just be an S3 bucket or a simple web server with some JSON files that hold order details arranged systematically on disk inside the webroot.
@qj0n
@qj0n 6 месяцев назад
@@barneylaurance1865 ok, so let me rephrase what I wrote: 404 might mean technical server error (should be 5xx, but I think some servers like IIS return 404 when no binding on some url), no particular resource or no particular resource type. Which makes troubleshooting a bit complicated
@dasten123
@dasten123 6 месяцев назад
Trying to figure out what a good REST-API looks like (for real-world applications), was the most difficult ordeal for me when becoming a software developer. And I lost a huge chunk of my sanity in the process. The most infuriating thing was: Everybody is doing it differently and saying wildly different things about it. But that's the key.. think about it! Don't even try to master it, it's impossible when it comes to REST. So my tip: Don't try to find "the best" way, or just don't call it "REST" and do whatever works.
@asagiai4965
@asagiai4965 22 дня назад
Just be consistent at yourself first.
@spicynoodle7419
@spicynoodle7419 6 месяцев назад
All rules are suggestions if nobody is enforcing them :)
@RealDieselMeister
@RealDieselMeister 6 месяцев назад
BE Consistent: Not when you have different domains. The domain tells you, how to name things and that can be different between domains, event if they represent maybe the same concept!
@jagertee
@jagertee 6 месяцев назад
Most often you design an API for the purpose of being used by a bespoke frontend. In this case it usually does not make sense to follow a REST spec by the letter just for the sake of conformity or to please a senior dev like me. If its plural or singular or a weird naming convention: the machine does not care. APIs should fit the use cases of the frontend or system consuming the API, not vice versa.
@jeroen7362
@jeroen7362 6 месяцев назад
A put and a post and a get etc should not matter to what your functionality is intented to do. Just pick the best verb/method for transport. Nothing wrong with a post to get something. A filter query that contains a bunch of filters and order by etc is very clean in a json body, a GET forces you to put it in an url query string and that makes it horrible, and very hard to craft tests for.
@BosonCollider
@BosonCollider 6 месяцев назад
There is something wrong with post to get something: you lose the copyable link to browser
@jeroen7362
@jeroen7362 6 месяцев назад
@@BosonCollider I see, a get also does not work usually for me as i need to provide a bearer in the header to authenticate i test api's with postman or directly from rider http tools
@awmy3109
@awmy3109 6 месяцев назад
It's wrong to use post or put for retrieving data. There's nothing good about it please.
@awmy3109
@awmy3109 6 месяцев назад
​​​@@jeroen7362Your client should not determine how you design your API. You will change your API when you are not using Postman? Silly reason for using post or put for retrieving Change your client if it's getting in the way. Not your API.
@jeroen7362
@jeroen7362 6 месяцев назад
@@awmy3109 well i my view transport should have nothing to do with your functionality. a post and a get are just a means of transport. if a post makes sense because you have a payload in a body. that payload can contains filters and sorting parameters or an array of codes you are requesting for. So if that is what i need to send over to query data, i have to use a post, and there is nothing wrong with that. only rest purists have a problem with this.
@jbeaudoin11
@jbeaudoin11 6 месяцев назад
I think we have been in a bad place in the web. The blinds leadings the blinds. Hate it when someone gives me the argument of "facebook does it like that".. Are we facebook ? Obv not.. Can we actually understand what we are trying to solve and not just "copy paste" what others do. Big thanks for "problem details" first time i see this and it looks nice at first glance. It's something i do struggle with. Also hypermedia look interesting and solve some problems but I'm a bit confused about some part of it. Like how do you send data with the request ? If you need user inputs feels kind of wrong.. gonna look more into this. And to close that essai, any thoughts on batch and bulk endpoints ? Batch like MIMD and bulk like SIMD. Batch example, create multiple but different entities. Bulk example, cancel multiple orders at the same time. I don't like batch much, i tend to do bulk more often. Bulk can help you optimize a lot of the database calls like single shared fetch during business logic validation.
@adambickford8720
@adambickford8720 6 месяцев назад
A very ivory-tower, overengineered view. In 20+ years i've never seen HATEOAS used irl. Even the PoCs of yesteryear are janky. At some point you have to be pragmatic and admit it doesn't work irl. A lot of these are just opinions, and contradictory at that.
@edwardevlogiev4087
@edwardevlogiev4087 6 месяцев назад
You see and use HATEOAS every single day while viewing pages, clicking on links, and thereby driving the next application state.
@RealDieselMeister
@RealDieselMeister 6 месяцев назад
@@edwardevlogiev4087 Bla bla bla... In a world of open api, swagger or whatever, HATEOAS is a relic from the past. Clunky and too much noise for a simple api. See, how opinions are different?
@edwardevlogiev4087
@edwardevlogiev4087 6 месяцев назад
@@RealDieselMeister You have no idea if I agree or disagree with the video, but still are arguing with my "opinion". I'm commenting that @adambickford8720 sees HATEOAS being used every single day (irl, as he put it), no that he uses it or must use it.
@steveofficer9255
@steveofficer9255 6 месяцев назад
You are both correct. HATEOAS is not a relic from the past. It is literally what the web uses to navigate between pages. Your main argument is that it isnt applicable to the systems you work on. So dont use it. Push back against the manager/marketing nonsense that everything is REST. Because it isnt
@LtdJorge
@LtdJorge 3 месяца назад
RFC 7807 has been obsoleted by 9457 hehe
@gryg666
@gryg666 6 месяцев назад
I have to say, working with Shopify API is a nightmare. Not wondering it was mentioned here few times.
@asagiai4965
@asagiai4965 22 дня назад
Do use 404 (if not found) Don't use inappropriate http code. Also consumer context matters. Rule #10 if it is security, you don't really need to put unauthorized.
@asagiai4965
@asagiai4965 22 дня назад
Based on what is going on so far, this looks more like someone's ideal standards.
@camiloanavas
@camiloanavas 6 месяцев назад
His arguments about 404 are solid. What do you recommend?
@GnomeEU
@GnomeEU 6 месяцев назад
404 for me means I got the wrong URL. Misusing the http status code for something like, "order not found" is super weird to me. Love the video.
@barneylaurance1865
@barneylaurance1865 6 месяцев назад
You did get the wrong URL. You thought you had a URL of an order, but there's no order at that URL, therefore you got the wrong URL.
@GnomeEU
@GnomeEU 6 месяцев назад
@@barneylaurance1865 so how would i decide whether that's an expected error or a system error? Maybe the service is just down. Seems like a way to confuse your api consumers.
@noahg2
@noahg2 5 месяцев назад
Can we please name these as opinions rather than best practices? I don't care if the guy has Ph.D in Computer Science this at the end of the day is an opinion from a person and not the "official best practices that everyone should follow when building REST API" book from Roy Fielding himself or from some organizations like ECMAscript or .NET foundation.
@CodeOpinion
@CodeOpinion 5 месяцев назад
I've said in another video, I wish best practices were called "maybe something you should think about when X, Y, Z and here are the trade-offs". 😂
@Sousleek
@Sousleek 6 месяцев назад
In rule #8 there is actual problem. It has nothing to do with "industry standard" The problem really exists. When server returns 404 how can you be sure that your application is not misconfigured with wrong URLs of upsream services, or maybe gateway team just broke the namespace? May be simply particular object was not found? In our company we consider object abscense as one of forms of the "business error" and explain that in response body in unified format. All our business errors has 418 code. So when client gets 418 it knows that he should parse body to get whar really happened. This probjem exists in environments where RPC is implemented in form of HTTP API (ant they call it REST but it's not). On my opinion its 80% of all interfaces that i ever saw.
@csmrfx
@csmrfx 6 месяцев назад
Confusing literary efforts with some loose API profile? Yes. Conflicting your names inside your RDB tables and object classes with plurals in the API? Yes. And so on until you get the fact that this "guide" isn't actually that good...
@RasmusSchultz
@RasmusSchultz 6 месяцев назад
I feel you skirted around the 404 status issue a bit too easily? you didn't even cite the arguments, or attempt to refute them - which is a shame, because there's a really good argument in there about causing bugs in the end user's client code. 404 status codes in APIs are ambiguous. Being pragmatic? sure, always - but I think the whole industry needs to reconsider this one, because it causes real issues. it's not always pragmatic to just throw your hands up and go "but that's what the industry does". sometimes, a whole industry *can* be wrong.
@CodeOpinion
@CodeOpinion 6 месяцев назад
That's was my point in various aspects of the video, the whole industry can be wrong. And a lot of the other "rules" were to just follow the industry, but in this case, they chose not to. I agree I didn't give my opnion much on this one heavily, but it relates to what you define as a resource. If a resource isn't found then it's a 404. What's a resource? Whatever you want it to be. If you decide that your resource represents a database record because it has path segments as IDs, then sure, so be it. In my other example with having the idempotent ID in the URI, that's a very unique resource.
@jeroen7362
@jeroen7362 6 месяцев назад
My bestpractice rule is to not mix transport and protocol with your functionality. So whatever your transport is (bus, email, filesystem, ftp, fax, http) do not use the errors of that transport in your code for functional meaning. a 404 should only mean that you have called the wrong url, the transport/protocol failed. it does not exist. if your url was fine and your resource you requested is not found you should not get a bad request either, just a 200 with in it functional content, a functional errorcode and message, {succes:false, errormessage: "this book is not for your age" , errorcode : 10}. A http code 200 never shows up as an error in your logging system as it should not. a 404 and a 400, 401 403, etc pollutes your log with stuff you really do not have to look into. An exception in your log should mean that something went wrong, maybe a hacker was testing your apis, you should see those as 404. if he tries to get in you should see a 401 in your log. a 500 means your api died and not that you have send in some variables that did not make sense to the api.
@SeaBike007
@SeaBike007 6 месяцев назад
> do not use the errors of that transport in your code for functional meaning Taking this to an extreme, a 500 should be a 200. The transport made it to the server & then back, ergo 200. I do disagree, I've had some people try to impress on me very strongly that the HTTP result code *should* very much map to the application result. I do agree that bad-args should be a 400. I think in this comment I was going to see a suggestion to not use 410 but instead 400 for bad user args. Further, having 400 vs 404 vs 500 in logs is really great. Seeing a surge in 400s where none are expected can be a good indicator. I do agree that someone manually trying URLs should not be able to overly pollute logs nor trigger any meaningful alarms (unless they are actively degrading the service, or perhaps a 'security' alarm, but no log-scan type of alarms should be triggered by someone trying a bad URL half a dozen times)
@jeroen7362
@jeroen7362 6 месяцев назад
@@SeaBike007 Well those people were impressing strongly on me too but i see no argument for it, for REST it was just convenient to overload errorcodes and give them more then one use. It does not make it a good idea. A 500 needs to be in the log when your api is crashing badly, a 500 because of some strange user input that does not make sense needs no 500 because all transport and api's works perfectly. just return a functional errormessage with status 200 and in it something like succes=false, message=can not devide by 0. A 404 401 etc should only show up when an api can not be found or access denied when that is not expected, so a hacker is unexpected and should show up in the error logs for shure! when there is a lot of hacking and fishing going on you need to take counter measures. But i do understand that what i am basically saying is that REST is a bad practice in "my book" I focus on maintainabillity (only real problems in a log, every exception like a 404 500 is unexpected and needs follow up.) and functionality. I have much more functional errors that need to be dealth with then just the few http errorcodes. So i state that those errorcodes are meant for the transport and not for application logic. Wen you switch from http to a message bus you do not get 404 on the transport. why should your code need to be dependend on the transport errorcodes?
@MarekFr
@MarekFr 6 месяцев назад
@@jeroen7362 Returning 2XX status codes for a failure (either of the client or the server) is literally the worst thing you can make as an API developer. You're arguing with polluting the logs, but that is a non issue if your API is designed properly, since you can hapilly ignore 4XX codes, as those are user errors. "A 404 401 etc should only show up when an api can not be found or access denied when that is not expected" - those are exactly uses cases for 5XX status codes, lol. You know basically nothing about HTTP standard as far as I can see and with each "point" you're trying to make, the more it is visible.
@jeroen7362
@jeroen7362 6 месяцев назад
@@MarekFr Well i see you try to make a point but without any argument. You only speak of what is told to you without thinking if it makes sense or not. If you have a good argument why it is a good idea to overload errorcodes of a transport to mean more then one thing let me know the actual argument to do that. Also you are wrong about the errors itself if you would use them. a 5xx is really not intended for not found 404, not authenticated 401, or not authorized 403. Ff an api is not found you are not in charge of the errocodes, the transport will throw it for you. Read the docs again and lol at your own reaction. http 404 means that there was nothing at that url (resource not found) it means the api is simply not deployed anymore at that adress, or it is there but the dns is not pointing to that host. or the api client is configured with a wrong url. when i see that in my log files (azure insights is what i work with) i know something is wrong, why would a 404 happen if all is expected to function without problems? So i have to find out and fix it. Now all you resties are overloading the 404 and use it when a book is not found by the api. Who cares? i do not want to see those errors in the log, it is not an exception for the transport, everything works! the book was just not found, that is a functional error not a technical transport error and therefore it should not raise red flags. a 500 and 503 etc is a real red flag it could only show up if your api is down or failing, it somehow did not handle its exceptions internally and fails badly. if to many 500 show up it will even trigger Rapid Fail protection in iis and reboot the whole api. Yes you do your thing as you like, but i know my stuff.
@MarekFr
@MarekFr 6 месяцев назад
@@jeroen7362 What do you mean transport? Transport layer is TCP, HTTP is application layer. If a server is not found, your request will timeout or throw DNS error, not 404. You should really read HTTP standard before you make any arguments which don't even make sense.
@gordondaniel
@gordondaniel 6 месяцев назад
Plural 's' - NO. That is a very old rudimentary from databases, when table names used to have 's' - which is also wrong.
@mindasb
@mindasb 6 месяцев назад
If that's what everyone is using in an industry where we can't standardize almost nothing above the transport layer then YES, oh hell YES!
@penguinzwarrior4679
@penguinzwarrior4679 13 дней назад
I cannot follow what you are saying half of the time. Please speak in a less convoluted manner. You often start making a point, then you stop mid way, the you go back to another point and then return to your original point. You are chaining multiple unfinished statements and it becomes confusing. I had to rewind multiple times because a few things didn't make sense. You literally said nothing from 01:32 to 01:53. That was a word salad that didn't feed anyone. Another example, when you were explaining about the timestamps: "But I am gonna add a little bit to this, I am gonna have a link at the very end of this video to a video I've done about storing date-time, specifically not just UTC. Because date-times in the future not so much." I might be missing something, but "no so much" WHAT?
@CodeOpinion
@CodeOpinion 13 дней назад
This video specifically or others have the same issue for you?
@penguinzwarrior4679
@penguinzwarrior4679 12 дней назад
@@CodeOpinion This is your first video I stumbled on so I don't have other observations. I didn't mean to make it negative, I was just frustrated that I couldn't understand some of the points you were making. It's possible that my confusion stems from lack of experience, maybe other viewers didn't have this issue but for me it was difficult to follow. Maybe I would have been able to connect the dots if I had more experience but I think everyone would appreciate it if you spoke in a more structured and straightforward way. For example, you mentioned hypermedia a few times. I don't understand how it relates to the topic. I suppose you don't mean hypermedia as in audio and video but something else.
@gordondaniel
@gordondaniel 6 месяцев назад
Complex 'id' field concatenated with '_' is NOT GOOD: (23_123456_321654789) 1. Api users also software - and they also want a fast integer key access, uniqueness, auto increment with time (ordered) info. 2. If your 'id' field contains 3 different information details - it means someone needs to parse it into those 3 different fields anyway - so just have those 3 different information details as fields, and keep the 'id' the auto increment integer. 3. Sometimes complex concatenated field is valid, but not for 'id'. Usually it is something related to integration with other systems, and I call it 'code' field. Like 'Customer' has a field 'code' which is a unique string that is composed of a 'category', 'region', 'serial' (C_123_321654).
@Sammi84
@Sammi84 6 месяцев назад
Some systems have security requirements where they are not allowed to leak information like the ordering of items, and size of collections, and relative timings of creation of items. And auto increment ids will leak all these things. The fix is to either use some large random id or to encrypt ids before providing to clients. Both will be string ids then.
@gordondaniel
@gordondaniel 6 месяцев назад
@@Sammi84Interesting point. if my 'id' field is classified - I would omit it from the api, and have a dedicated 'key' or 'code' field for the unique identifier I expose to the api users. Similarly, I omit 'password' field in my 'Auth' entity (which represents a user login registered in the system).
@Silky987
@Silky987 6 месяцев назад
@@gordondaniel I agree 100%. Omit the filed, hash the field, or use a non-detail leaking generated code. Either way, your api will know how to translate it back to a useful value.
Далее
Avoiding long running HTTP API requests.
7:24
Просмотров 13 тыс.
Design Microservice Architectures the Right Way
48:30
Просмотров 707 тыс.
3M❤️ #thankyou #shorts
00:16
Просмотров 3,9 млн
Я нашел кто меня пранкует!
00:51
Просмотров 468 тыс.
Beware! Anti-patterns in Event-Driven Architecture
10:34
API Gateway Explained Quickly
4:23
Просмотров 10 тыс.
Rest API - Best Practices - Design
15:50
Просмотров 98 тыс.
Goodbye long procedural code! Fix it with workflows
9:05
"Serverless sucks!"... or does it?
7:27
Просмотров 7 тыс.
What is an API Explained in 1 minute #shorts
0:46
Просмотров 178 тыс.
ПОКУПКА ТЕЛЕФОНА С АВИТО?🤭
1:00
ИГРОВОВЫЙ НОУТ ASUS ЗА 57 тысяч
25:33
Урна с айфонами!
0:30
Просмотров 7 млн