18 ms·
Best practices for REST API design (2020)
- veesahni 6y agoI've written a comprehensive one on this topic a few years ago: https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api https://www.vinaysahni.com/best-practices-for-a-pragmatic-re...
- gmanis 6y agoThank you for this. It is my go to post every time I implement an api service or even for web development.
- struct 6y agoI’ve also found the Microsoft API guidelines helpful (especially for error handling). https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md https://github.com/microsoft/api-guidelines/blob/vNext/Guide...
- majkinetor 6y agoWay better then this one, however only covers CRUD.
- slimbods 6y agoNice reference, but like the OP article, it really goes light on security. I feel that's the hardest part of getting an API released.
- babyyoda 6y agoGreat post. Nothing flashy, walks through basics and principles. I do love the simplicity of REST and unless you need some graph would recommend folks stick with it over GraphQL
- pfarrell 6y agoWhen I looked into implementing GraphQL, it didn’t seem to require the data I was serving be a graph. I found the big difference with REST was that GQL allows the consumer to define the properties returned rather than having backend engineers have to think through every use case. It wasn’t enough of a killer feature to risk the timeline on that project, so my experience is limited.
- yxhuvud 6y agoBackend engineers still need to think through every use case to decide what fields to expose.
- numlock86 6y ago> Then if we try to submit the payload with the email value that already exists in users, we’ll get a 400 response status code with a 'User already exists' message to let users know that the user already exists. With that information, the user can correct the action by changing the email to something that doesn’t exist. I was always under the impression that 409 would be the "correct" code here, while you'd use 400 if the API user didn't supply an email at all, for example.
- ed25519FUUU 6y agoIsn’t 409 if you’re trying to update an existing record (PUT) and not create a new record (POST)? The ambiguity is probably why most people just use 400 and call it a day.
- BerislavLopac 6y agoThere's this, FWIW: https://i.stack.imgur.com/whhD1.png https://i.stack.imgur.com/whhD1.png
- motogpjimbo 6y agoPlease tell me that's satire...
- motogpjimbo 6y agoIronically, your comment is a perfect illustration of one of the problems with REST - its tendency to provoke discussion about things that don't actually matter in practice. No user cares whether an error response came back with a 400 or a 409 status, or what those codes even mean. It's madness that as a profession we spend so much of our employers' time and money on trivial things that deliver no value whatsoever. Response codes, HTTP verbs and pretty hierarchical URLs are all meaningless. I've lost count of the number of meetings I've been in where there have been pointless, timewasting debates about these things. Should we expose separate /foos and /bars endpoints? Should it be /foos/{foo_id}/bars/{bar_id}? Or maybe both? Do we need a POST, a PUT or a PATCH? Etc, ad nauseam. I'm generally cautious when it comes to embracing new technologies, but I've wholeheartedly embraced GraphQL simply because it has removed countless hours of unproductive bikeshedding from my professional life.
- throw_m239339 6y agoAll these "best practices" are exactly why I embraced GraphQL quickly and flushed "REST" down the toilets for big projects (http+json is fine for small ones, since no lib overhead). GraphQL is unashamedly the new SOAP. I.e. we have a spec, not a series of "best practices" thus endless architectural debates where people are shamed for 'doing it the wrong way' online. - Accept and respond with JSON: No, why? what if I want to work with XML? or format X or Y? - Use nouns instead of verbs in endpoint paths: I don't care about that - Name collections with plural nouns: I don't care about that - Nesting resources for hierarchical objects: No, why? - Handle errors gracefully and return standard error codes: nothing to do with REST specifically. - Allow filtering, sorting, and pagination: yes, good luck coming up with the right query structure and sticking to it. - Maintain Good Security Practices: nothing to do with REST specifically. - Versioning our APIs: And here we are. How many HATEOAS people claimed it was blasphemy and it missed the point of REST? None of these are an issue with GraphQL, just like they weren't an issue with SOAP. You get a schema both the client and the server must agree with, end of story. As I said to a dev once, if your 'best practices' can't be automated with a CI tool, then you need to worry about creating that tool first...
- quercusa 6y ago> GraphQL is unashamedly the new SOAP ...may not be the advertising you think it is.
- btmcnellis 6y agoA kinder way to put it might be "SOAP with the benefit of hindsight."
- fc373745 6y agoNever understood the hype around GraphQL. You want to know how to halve your performance and responses/s on your service? add graphql. All things that GraphQL claims to do can be implemented in RESTful services easily. If you want specificity in your query fetching, just add query params or put them in the request body If you want schema validations, there are many libraries that help you with that. And if you want data from multiple resources from different endpoints, what exactly is stopping you from implementing that in REST? Also, GraphQL has a steeper learning curve as opposed to REST. never understood graphql. To me its just an abstract layer between the front end and back end, adding to the already complex stack.
- seliopou 6y agoI interrupted my reading at 'Accept and respond with JSON' to write this comment, before I skipped over that section and returned to reading the rest. Folks that aren't aware of Webmachine should take a look: https://github.com/webmachine/webmachine https://github.com/webmachine/webmachine The 'Accept' header should determine the response type, but content negotiation is something that few bother to implement. Webmachine does that for you, among other things like choosing the correct status code for your response. Also, shameless plug for my OCaml port: https://github.com/inhabitedtype/ocaml-webmachine https://github.com/inhabitedtype/ocaml-webmachine
- dmitriid 6y ago> The 'Accept' header should determine the response type Also, the HTTP decision diagram: https://github.com/for-GET/http-decision-diagram/tree/master/doc https://github.com/for-GET/http-decision-diagram/tree/master...
- Longwelwind 6y agoWhat is the usefulness of this feature? The only advantage I see is that your clients can choose the format they want to work with, but since the serialization format is just a message format that has no impact on the code, and that most of them have a bijective transformation between them, I don't see the point. If it feels like a lot of work (Or the added complexity of a moving part, if using the tool you linked) for next to no impact.
- dec0dedab0de 6y agothings like this are useful if you have a user that is integrating your api into some kind of legacy application that does not support json. Then in the future when JSON goes out of style, you could easily add support whatever the new format is.
- pionar 6y agoIf you don't care about others using your API, then don't do it. If you do, follow the standard which says you SHOULD have a Content-Type if there is a body to your response.
- throwoutttt 6y agoGraphQL is far superior for development speed, API flexibility and extensibility, authorisation, discovery, testing, and less bugs.
- kitd 6y agoBut not for range of clients
- throwoutttt 6y agoTrue
- pugworthy 6y agoA question I’ve always had about 404 and APIs... How do you distinguish between an invalid path (no end point) and a valid path requesting a resource that doesn’t exist?
- throwoutttt 6y agoYou don't
- pugworthy 6y agoI can just see some developer going nuts and pulling out their hair because they can't figure out why a call to query a customer keeps saying the customer doesn't exist when clearly it is in the database. Until they realize they gave the URL path as "/cutsomer" instead of "/customer" in the code.
- mariusor 6y agoIf doesn't exist means it has been removed: 410 Gone, if doesn't exist means not yet created: 404 Not Found. I can't think for other types of not existing, or why you'd need to differentiate between them.
- pugworthy 6y agoSay I have an API with a path of /customer/<id>. I call /customer/235235 and customer 235235 doesn't exist. That's a 404, resource not found. But say I make an uncaught error with the path and call /cutsomer/235235. That also is a 404, resource not found. It really depends on what you want the word "resource" to mean. It gets a bit more complex if you have a simplistic website with an API service both on the same server. For your users, you want a nice 404 page for mistyped or dead links. But you don't want your API also triggering that same page. Beyond actually splitting your main web content and API into two servers, I could see returning a 400, Bad Request response for the API to avoid triggering a 404 handler. After all if you give it a customer ID in the above case that doesn't exist, it is essentially a "bad input parameter" and the error message can indicate which parameter (the customer ID) and why it's a problem (there is no such customer).
- agentultra 6y agoI'd recommend against using `v1` in the path and prefer content negotiation: GET /resource/1 Accept-Version: ~1.0.2 ... Implementation-wise this ends up with better code (and less code) on the back-end and a reduced number of HTTP routes (which should represent the entities and be maintained). The pain of REST is that there's very little in terms of "correct" as we don't have a formal specification of the semantics. If you end up using /v1 it's not any more or less REST-ful.
- idlewords 6y agoI'd recommend the opposite, as with a versioned URL you can very easily route stuff to different machines by simple URL inspection and have a very clean separation between versions.
- dnautics 6y agoUnless you're talking about a human dispatching the request (url toolbar or via tool like curl) There's nothing special between a url path or a content header Either way it's layer 7 routing. What was the advantage again?
- packetlost 6y agoLoad balancers/reverse proxy have first-class support for routing based on paths, but support for routing based on headers is trickier or not possible depending on the software.
- wtetzner 6y agoI think they're useful for different things. Media-type versioning is useful for supporting different data types/representations of the same resource. URL versioning is useful for versioning resources themselves and their behavior/business logic.
- pkulak 6y agoI dunno. We started doing something like that at my company (we actually use the plain Accept/Content-Type headers, so "application/vnd.mycompany.service.v1+json") and it's been a giant pain. Routing based on headers sounds cool, but basically no backend OR frontend frameworks support it well. Even if they say they support, there are bugs or weird traps to fall into. Path versioning is just so much easier for everyone.
- mhoad 6y agoJust for a point of reference here is Google’s take on the exact same topic. It has a bit more of a gRPC background but still is very REST friendly by default. https://cloud.google.com/apis/design/resources https://cloud.google.com/apis/design/resources Also as one of the most common pushbacks people have with gRPC is that everyone generally expects JSON still in 2021 especially in the browser. Not sure if this is super well known or not but gRPC integrates well with things like envoy which allow you to write a single gRPC API and have it serve and respond to both native gRPC and standard REST / JSON calls.
- packetlost 6y agogRPC is also a 300lb gorilla of a framework for communication and has huge problems with versioning if you aren't "running at HEAD".
- mhoad 6y agoMy original comment might have given the impression that I was some gRPC guru when in reality I’ve only played with it very briefly. What are the versioning problems with it? I was under the impression that it was actually designed from the start to be fairly flexible with regards to changing API methods etc
- packetlost 6y agoWell I wasn't referring to API versioning, I was referring to the actual lib versioning. All of Google runs basically at HEAD and nearly all of their libraries reflect this. In a distributed system, if you update one of the GRPc library versions, you need to update all of them otherwise you can run into weird failures.
- jrockway 6y agoThat might be true, but at least when I was at Google, people were not building and releasing their software to pick up HEAD of libraries they depended on. Some binaries running in production could be quite old and seemed to communicate with newer builds just fine. (I suppose if there was a problem someone would have built a new version, though.)
- haidrali 6y agoI always found this document by Microsoft very very good https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design https://docs.microsoft.com/en-us/azure/architecture/best-pra...
- switch007 6y agoIf only some teams at Microsoft would read that. Man some of their APIs are annoying
- Mordisquitos 6y agoSmall typo-ish error in the article, emphasis mine: > 401 Unauthorized – This means the user isn’t not authorized to access a resource. Surely that should say that the user isn't not unauthorised?
- s_dev 6y agoNo, just "isn't authorised" is clear. The triple negative is a bit much.
- throwoutttt 6y ago403 is unauthorized (forbidden due to authorization policy). 401 is unauthenticated (not logged in). Very important difference for clients handling authentication state.
- Mordisquitos 6y agoThat is not false, I didn't not fail to notice that after fixating on the incorrect double negative! However, not to be unfair, 401 is unfortunately not named "unauthenticated", even though it's conventional usage (as you point out) is not unintended to actually mean lack of authentication rather than of authorisation.
- snarfy 6y agoI always have mixed feelings about using plurals for naming. Pluralization in English is extremely inconsistent. cat -> cats, dog -> dogs, child -> children, person -> people, etc. It makes my code feel inconsistent too. Sometimes I use more specific typing to resolve this, e.g. PersonList , but I'm not sure that's any better.
- dliff 6y agoI've gone back and forth on this in respect to database tables and ultimately prefer singular. If the table is named "profile", I think it's obvious that it can store more than 1 profile, since... well it's a table and has rows.
- adamrt 6y agoAgree. I've always preferred the Django vs the Rails way on this. Django uses pluralization only for display purposes. Things are object_detail (singular) and object_list (plural). It just assumes 'append s' for plural displays, unless you override. I like the _list suffix instead of trying to pluralize
- sidpatil 6y agoI don't see a problem with writing "childs" or "persons". In this scenario, consistency is more useful than grammatical correctness [1]. And the simpler pluralization logic makes it easier for non-English speakers to work with the codebase. [1] Related example: https://en.wikipedia.org/wiki/HTTP_referer#Etymology https://en.wikipedia.org/wiki/HTTP_referer#Etymology
- nojvek 6y agoI’d say REST apis should also support selections. E.g I only care about these fields. It’s the #1 reason why graphql is so popular. You only fetch what you want. But I have missed feelings about graphql. I wish they didn’t invent a new language, it was just json. I’ve encountered so many little bugs because graphql parsing is different between different servers. Ideas of graphql are great, implementation seems over complicated. REST is much easier to grok.
- Octoth0rpe 6y ago> It’s the #1 reason why graphql is so popular. You only fetch what you want. It's certainly one of the main sales points for graphql. On the flip side, I've never been frustrated by getting too many fields back from an API. I suppose if I was developing exclusively in extremely bandwidth limited contexts where getting back only 2 fields rather than 50 actually made a difference, I might care. It just seems like such a non-issue to solve/talk about in almost every other context.
- lukeramsden 6y agoIt's likely more of an issue if you're wanting to fetch lots of nested data in one request, but only a few specific fields of what could be an extremely large object, like say the just the names and profile picture URIs for a large set of users that have interacted with the object your fetching. This is particularly relevant to social media, such as Facebook.
- treve 6y agoFor the cases we've hit, it made sense to do a more specialized endpoint (or media type) than to create a universal way to let clients pick that fields they want. This works way nicer with caches and APIs where the URI is a first class citizen.
- n_e 6y ago> On the flip side, I've never been frustrated by getting too many fields back from an API A pretty common use-case I have is needing to support these three things : - A “big object” list screen (where retrieving the whole objects would make the query return megabytes off data) - A “big object” details screen (where I need the full object) - Programmatically getting many big objects With GraphQL it involves writing one (or two) straightforward queries, while with REST it would require more thought or code.
- danielovichdk 6y agoDesign is hard. In the given example we work with an Article domain. Where there are Comments. Fine and totally fair. But how would you design your object graph from the bottom up? Articles and Comments is a fairly simple example. Imagine a Transaction in bank domain context. Would you have an endpoint like so? transactions/:id/acoount/:id Or perhaps transactions/:id account/:id/transactions Whatever you pick you must find a way for transactions and accounts to work together on a design level, which will impact how you potentially serve services and how you deploy them. Is an account and a transaction part of the same domain and service? It's hard to design proper REST apis because although it's easy to dish out cool looking routes, it might be a lot harder to actually design your systems based on those routes.
- JimDabell 6y agoREST doesn’t really have the concept of endpoints. That’s a hierarchy some people artificially impose over the top of a REST system. REST doesn’t require it. All of your URLs could be randomised and a REST system would work exactly the same. You don’t need hierarchy in your URLs. If you want to load a transaction, then /transactions/123 is fine. If you want to load an account, then /accounts/456 is fine. You don’t need to put one under the other. In a REST API, the primary key for a resource is the URL. If you have the primary key, URL hierarchy is unnecessary. Just use whatever is clearest for a developer to identify at a glance for debugging purposes. It’s not required by the tech.
- NanoWar 6y agoThis is true and I use top level URLs for all of my resources in a REST api. You can however to a POST to articles/:id/comments and return location headers pointing to /comments/:id easily!
- mewpmewp2 6y agoIt would be for all transactions /transactions and for transactions for a particular account /accounts/:id/transactions.
- tsimionescu 6y ago
- ngrilly 6y agoDo not use a page argument for pagination. If you have another process/client concurrently adding/removing items, then some items will be returned twice, and others will never be returned. It is better to use, for example, the ID of the last returned item as a starting point for the next query.
- kaoD 6y agoAs a user I expect that to happen. Cursors on the other hand are awful for getting to arbitrary pages, they are mostly useful for "More" links as on HN or Reddit. It's a trade-off.
- felixfbecker 6y agoCursors are also the only reliable option for supporting programatic usage for automation use cases.
- masklinn 6y agoI’d say they’re right: cursors are way better for an API. Pages are way better for a person. This here is about an API.
- matt-attack 6y agoWell good luck giving your users direct page access when your API only supports cursors.
- tstrimple 6y agoHow often do people really jump to an arbitrary page? I'd say filtering / searching capabilities are far more important for users than paging.
- _nothing 6y agoIt depends? If I'm looking for a new desk on IKEA's online catalog then I care more about filtering/searching, but if I'm reading through a conversation on a forum and want to be able to link to certain sections then I want that paginated.
- hardwaresofton 6y agoIf you want a pretty decent REST-ish API right out of the box, and you already have a DB, check out PostgREST[0]. More features than you can shake a stick at, and all you have to do is maintain your DB schema. [0]: https://postgrest.org/en/v7.0.0/ https://postgrest.org/en/v7.0.0/
- majkinetor 6y agoI like it and its very fast. Good luck with scaling and automatic testing tho.
- hardwaresofton 6y agoFrom-scratch or from-fixture E2E tests to prevent regressions should still be doable though, just gotta bring along your language of choice, and keep a repo around to hold the code/data.
- bigmattystyles 6y agoA bit of an aside, when it comes to querying against a data store, I’ve always wondered why odata is not more popular. In my mind, it’s wonderful.
- JoshuaEddy 6y agoLooks like a ripoff of this post from June 2019: https://www.merixstudio.com/blog/best-practices-rest-api-development/ https://www.merixstudio.com/blog/best-practices-rest-api-dev...
- pugworthy 6y agoIt's a common design style it seems. O'Reilly's REST API Design Rulebook reads similarly... https://www.oreilly.com/library/view/rest-api-design/9781449317904/ https://www.oreilly.com/library/view/rest-api-design/9781449...
- jessaustin 6y agoTFA: Posted 17 August 2015
- YesThatTom2 6y agoAPI Practices If You Hate Your Customers https://cacm.acm.org/magazines/2019/12/241052-api-practices-if-you-hate-your-customers/fulltext#.YDPtRI4BY98.twitter https://cacm.acm.org/magazines/2019/12/241052-api-practices-...
- p_l 6y agoPretty good, though I disagree with their opinion on SOAP ;) Many REST APIs have problems for the same reason SOAP had, and it involves lack of deliberate API design and abuse of "automagic code generation"
- mobjack 6y agoUsing HTTP methods as verbs is a terrible practice. It works for simple CRUD APIs, but it becomes too limiting once there are more than one way of updating something. It ties the API design too closely to the data model and usually means that the client has to implement more business logic instead of handling that on the server. Good API design should decouple business logic from the HTTP spec.
- saila 6y agoThe basic HTTP methods work in the vast majority of cases. The key is to create the appropriate resources--facades that compose the data model and business logic as needed.
- majkinetor 6y agoNo they don't work for vast majority of cases. They work only for CRUD and imposing resources paradigm on everything looks alien.
- hcarvalhoalves 6y agoYou don’t need more than the HTTP methods as long as you reify requests as resources. Instead of “doSomeAction on resource” it’s “POST/PUT /resource/actionRequest”. The trick is stopping and trying to make everything work over CRUD of your main entity resources. HTTP resources don’t need to map to tables.
- cesarb 6y ago> Set the Content-Type header in the response to application/json; charset=utf-8 without any changes. The "; charset=utf-8" part is not necessary and is ignored. See https://tools.ietf.org/html/rfc8259 https://tools.ietf.org/html/rfc8259 which defines the application/json media type: "No "charset" parameter is defined for this registration. Adding one really has no effect on compliant recipients."
- saila 6y agoThis article doesn't mention linking at all, which is at the heart of REST. Without links, it isn't REST, and most of the suggestions don't have anything to do with REST per se. Most of it is just standard JSON-over-HTTP stuff that's implemented in a variety of frameworks and libraries. EDIT: To be clear, I don't particularly care if an API is "RESTful" or not, as long as it's well-designed and documented, but I think there are interesting/useful ideas in REST that are lost when it's conflated with JSON-over-HTTP.
- CharlesW 6y agoWe could use a name for "standard JSON-over-HTTP stuff that's implemented in a variety of frameworks and libraries". So what shall we call REST without HATEOAS[1]? "RESTless"? [1] https://en.wikipedia.org/wiki/HATEOAS https://en.wikipedia.org/wiki/HATEOAS
- incrudible 6y agoNo, a truly RESTless API must do away with all the other pointless HTTPisms in REST. If you're using any other method than GET or POST, or any other codes than 400 and 200, you're not truly RESTless.
- NanoWar 6y agoMost of the times I end up with put endpoints with verbs, because that often how businesses work. Objects and processes. Behind a REST resource there is a database table most in of the cases. But what if I want to send an email? POST /emails ? That's RESTless as well!
- incrudible 6y ago> This article doesn't mention linking at all, which is at the heart of REST. Please, just don't do it. Yes, I read the dissertation. It's just not a good idea, it has never given me any practical use whatsoever and has always made dealing with the API more annoying. > Most of it is just standard JSON-over-HTTP stuff that's implemented in a variety of frameworks and libraries. Yes, and we call that REST or RESTful anyway. We'll keep doing it that way. You're going to have to accept it.
- derkoe 6y agoMost of these best practices forget the hard parts of JSON/REST APIs: - How to handle date and time incl. time zones - JSON has no data type for that - Handling of numbers (JSON only has double, which does not fit most cases) - Defined and parseable error responses (rfc 7807 plus extra fields for details) - Localization - do you send translated texts or just error codes? - How to handle updates? Overwrite every field? How to update only some fields for a resource? Optimistic locking? - How to handle 1+n problems for reading? ...
- ehutch79 6y agoSend ISO date/time in utc. Send numbers as strings. you should be treating this as hostile in your backend anyways, and checking it. Send both an error code, and a string in simple english, or whatever your most common developer language is. If you care about only updating certain fields, track changes and only send those fields to the backend. These arn't really that hard.
- crescentfresh 6y ago> Send ISO date/time in utc what's an ISO date/time?
- deleted 6y ago[deleted]
- lyjackal 6y agoI assume GP means ISO8601 Date Time https://en.wikipedia.org/wiki/ISO_8601 https://en.wikipedia.org/wiki/ISO_8601. Default behavior of javascript date json serialization > JSON.stringify(new Date()) '"2021-02-22T20:34:53.686Z"'
- tshaddox 6y agoThen why add the "in UTC" part? ISO 8601 specifies how to designate the time zone.
- lucas03 6y agoZalando has amazing api guidelines - https://opensource.zalando.com/restful-api-guidelines https://opensource.zalando.com/restful-api-guidelines
- ibejoeb 6y agoI like their 429 guidance: https://opensource.zalando.com/restful-api-guidelines/#153 https://opensource.zalando.com/restful-api-guidelines/#153 This has massive implications in real-world systems. Rate limiting adds and order of magnitude complexity to a client system due to the next for delayed, conditional execution. So many APIs do rate limiting and don't bother to add information about why it is happening or for how long the limit applies. I've been working with a name-brand system that limits based both on client application and end user. So, effectively, there can be a 429 because the application as a whole is exhausted, or because a particular user is exhausted. There is no additional information, so the only way to know if the limit has lapsed is to try again. It make it incredibly cumbersome to create reliable consumer applications.
- phtrivier 6y agoWith the exception of url naming (no rule, which is worse than any rule), error response (a bit ambiguous) and general verbosity, I find that the jsonapi.org spec can serve as a relatively sane default. Although I would love for browsers to start natively supporting some sort of schema based, explicitly typed, binary format.
- holistio 6y agoThese are all valid, but what I mostly see is: "decade-old Rails conventions sprinkled with some Node examples"
- malandrew 6y agoI can't wait to see the day when a guide for best practices for REST API design just contains a single sentence: "Don't write any new REST APIs. Use something like gRPC instead." The only thing something like gRPC is missing that is very valuable from HTTP REST is having standard error codes corresponding to all the HTTP response codes (2xx, 4xx and 5xx codes)
- neuromage 6y agoI've also found Google's AIPs (https://google.aip.dev/general https://google.aip.dev/general) to be pretty useful when designing REST-based APIs.
- pachico 6y agoCache data as best practice? Sorry but no. Create fast read models, if you need them, yes.
- majkinetor 6y agoIndeed. You can easily make it very hard to scale.
- majkinetor 6y agoThis is very limited guideline. Nothing really new here, all those topics are covered all around for a decade. As usual only CRUD counts, no mention of operations, patch, links, aggregation of calls, ways to document API, token duration, rate limits etc. Adequate for todo list maybe.
- icod 6y agoOk the way I do it with Angular and Vue clients (and Go servers) is: GET /api/vn/singular_name/ = list all GET /api/vn/singular_name/?field=value = list all filter by query, if it gets more complex base64 encode the query and decode on server GET /api/vn/singular_name/:id = get by id POST /api/vn/singular_name/ = create PUT /api/vn/singular_name/:id = replace PATCH /api/vn/singular_name/:id = atomic update DELETE /api/vn/singular_name/:id = duh If models are related they receive a related_model_id field. This works even for "many to many". In the case of Vue there's this excellent library called vuex-orm, which handles normalization of incoming data and ways to define relationships or all kinds and also queries with or without related models. It's so good that I'm abandoning Angular because it doesn't have something so sophisticated, despite it having the better component system and structure all together. Not having to subscribe and unsubscribe to data streams and deal with this torture instrument rxjs is a bonus. Because of vuex-orm I'm more productive than I've ever been with Angular. This is sufficient and there is no need for GraphQL. Real time updates are simple. Whenever something like INSERT, UPDATE, DELETE happens an event is sent to a notification library which sends those updates out via websocket, a client version of this handles updates of the cache (or if you like vuex state, previously ngrx-data cache). The notification library also handles scoped status updates. Imagine a multi-community site. You're currently in community A and don't care about what happens in community B, the client tells the server "I'm in A" the server notifies the client only about the latest happenings in scope community A. Once you navigate to community B you do a fetch from the server to get the latest version of the truth. But while you're there you're also telling the server "I'm in B, send me real time updates about B". I'm not a fan of Redis. I like MongoDB and having a single database system for everything. Since I'm not into game development that's good enough. Postgres is nice for querying, I like SQL more than Mongo's way to query but when developing running migrations, database updates, it's a PITA, especially in Go which seems to lack tooling for this and the driver and "o"rm landscape is also a bit barren.
- rsj_hn 6y agoBy far the most important best practice is to keep the damn thing stable and online. I'd much rather integrate an API that doesn't change but maybe has a few pain points in developing the client than one where the client is a bit easier to develop but the API changes every year.