7 ms·
If you give access to your DB directly, your API effectively becomes your API with all the contract obligations of the API. Suddenly you don't completely contro
by Zvez 3y ago
If you give access to your DB directly, your API effectively becomes your API with all the contract obligations of the API. Suddenly you don't completely control your schema: you can't freely change it, you need to add things there for your clients only. I've seen it done multiple times and it always end up poorly. You save some time now by removing the need to build API, but later you end up spending much more time trying to decouple your internal representation from schema you made public.
- MoSattler 3y agoI think this point is addressed in the article.
- herodoturtle 3y agoCame here to say this too. From the article: > A less obvious downside is that the contract for a database can be less strict than an API. One benefit to an API layer is that you can change the underlying database structure but still massage data to look the same to clients. When you’re shipping the raw database, that becomes more difficult. Fortunately, many database changes, such as adding columns to a table, are backwards compatible so clients don’t need to change their code. Database views are also a great way to reshape data so it stays consistent—even when the underlying tables change. Neither solution is perfect (raw read replica vs API). Pros and Cons to both. Knowing when to use which comes down to one's needs.
- oreilles 3y agoVersioned views, materialized views or procedures are the solution to this. It is frequent that even internally, companies don't give access to their raw data but rather to a restricted schema containing a formated subset of it.
- vmfunction 3y agoIn addition if you are using postgres, then there is postgresRest to make api really quick and nice.
- tacker2000 3y agoOf course it’s possible, but now you need more people with DB and SQL knowledge. Also, using views and stored procedures with source control is a pain. Deploying these into prod is also much more cumbersome than just normal backend code. Accessing a view will also be slower than accessing an “original” table since the view needs to be aggregated.
- _a_a_a_ 3y ago> Accessing a view will also be slower than accessing an “original” table since the view needs to be aggregated. Where does it say anything needs aggregating. You can have a view that exists just for security. > Also, using views and stored procedures with source control is a pain. Deploying these into prod is also much more cumbersome than just normal backend code. Uh? This is normal backend code.
- Shorel 3y agoI don't see the problem here. Are modern developers allergic to SQL or what is the issue?
- tacker2000 3y agoNot all devs are proficient in SQL. Its another skill that is required.
- madsbuch 3y agowhy would you want to develop your api in sql over a traditional language? versioned views and materialized views are essentially api endpoints in this context. just developed in sql instead of some sane language.
- dvdkon 3y agoYou can let your API's users do arbitrary queries on any sets of data you expose if your API exposes SQL views directly. Plenty of apps don't need anything beyond basic "get by id" and "search by name" endpoints, but plenty others do. At that point, with traditional backends, you're either reimplementing SQL in your API layer, or creating a new endpoint for each specific usecase.
- camgunz 3y agoA lot of my backend career has been essentially Greenspun's 10th Law: Any sufficiently complicated REST or GraphQL API contains an ad-hoc, informally-specified bug-ridden slow implementation of half of SQL. SQL is a legendary language, it's powerful enough to build entire APIs out of (check out PostGraphile, PostgREST, and Hasura) but also somehow simple enough that non-technical business analysts can use it. It's definitely worth spending time on.
- rewmie 3y ago> Versioned views, materialized views or procedures are the solution to this. Wouldn't it be far simpler to just create a service providing access to those views with something like OData?
- vbezhenar 3y agoViews will severely restrict the kinds of changes you might want to do in the future. For example now you can't just move some data from your database into S3 or REST service. Stored procedures technically can do anything, I guess, but at that point you would be better with traditional services which will give you more flexibility.
- indigo945 3y agoA view can also do anything - it could query a REST service, for example. (Not saying that this is necessarily a good idea, though...)
- falcor84 3y agoIs that a real thing? What DBMSs support such views?
- jakewins 3y agoMost of the heavy artillery RDMSes at least, eg Postgres let’s you mount arbitrary HTTP resources as tables, which you then can put views over: https://wiki.postgresql.org/wiki/Foreign_data_wrappers https://wiki.postgresql.org/wiki/Foreign_data_wrappers
- remus 3y agoThis sounds like a total minefield. You might get a response in the same format, but I imagine it'd be very easy to break an API user who accidentally depends on performance characteristics (for example).
- ttfkam 3y agoAWS RDS and Aurora both support synchronous and asynchronous lambda invocations from the database. Should be used very carefully, but when you want/need a fully event-driven architecture, it's wonderful. https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL-Lambda.html https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Postg...
- Puts 3y agoYou can use stored procedures if you want to add another abstraction layer.
- Epa095 3y agoThey had stored procedures in the "old days" when they figured out that direct access to the database was a bad idea, so what has changed? (I agree that a DB view often is good enough thoug, but they ALSO had that in the "old days", IDK what has changed about that:-p )
- oldnet 3y agoAlso you shouldn't give up access to your DB for security reasons. That's why API exists at first place.
- vbezhenar 3y agoTechnically you can create different users with very precise access permissions. Might not be the good idea to provide that kind of API to the general public, but if your clients are trustworthy, it might work.
- berniedurfee 3y agoNo clients are trustworthy.
- camgunz 3y agoPostgreSQL 9.5 (7.5 years old) shipped row-level security [0] which solves this. [0]: https://www.postgresql.org/docs/15/ddl-rowsecurity.html https://www.postgresql.org/docs/15/ddl-rowsecurity.html
- yencabulator 3y agoThe architecture described in the article replicates the SQLite database on the page level.
- camgunz 3y agoYeah but this thread became about "you need an API".
- DarkNova6 3y agoThis 100%. My last customer used an ETL tool to orchestrate their data loads between applications, but the only out of the box solution was a DB-Reader. Eventually, no system could be changed without breaking another system and the central GIS system had to be gradually phased out. This also meant that everybody must had to use Oracle databases, since this was the "best supported platform".
- Dudester230602 3y agoOn the next iteration some consultancy will replace that with a bunch of microservices using a dynamic language. When that thing fails again they will hopefully settle on a sane monolithic API.
- archibaldJ 3y agoyeah reminds me of meteor JS
- londons_explore 3y agoYou could ship the database together with python/JS/whatever 'client library' - and you tell your clients that they need to use your code if they want to be supported.
- wmal 3y agoThis is the worst of both worlds. Not only are you back to square one, as you spent the time to build an API (client libraries), but now, if the API is limiting, the users will find ways of accessing the SQLite db directly.
- knallfrosch 3y agoYou just know they're going to run custom code, fck up their database and then still complain. I'm not tooo familiar with DBs, but I know customers. They're going to present custom views to your client SDK. They're going to mirror your read-only DB into their own and implement stuff there. They're going to depend on every kind of implementation detail of your DB's specific version ("It worked with last version and YOU broke it!"). They're going to run the slowest Joins you've ever seen just to get data that belongs together anyway and that you would have written a performant resolver for. Oh, and of course, you will need 30 client libraries. Python, Java, Swift, C++, JavaScript and 6+ versions each. Compare that to "hit our CRUD REST API with a JSON object, simply send the Authorization Bearer ey token and you're fine."
- marcinzm 3y agoAre you assuming clients will actually upgrade the library on a regular basis?
- qwerty456127 3y agoThat's [another reason] why you use stored procedures and only call them (rather than hardcoded or ORM-generated SQL queries) in your client app code.
- bennyelv 3y agoAbsolutely correct, listen to this article's ideas with great scepticism! The system that I'm currently responsible for made this exact decision. The database is the API, and all the consuming services dip directly into each other's data. This is all within one system with one organisation in charge, and it's an unmanageable mess. The pattern suggested here is exactly the same, but with each of the consuming services owned by different organisations, so it will only be worse. Change in a software system is inevitable, and in order to safety manage change you require a level of abstraction between inside a domain and outside and a strictly defined API contract with the outside that you can version control. Could you create this with a layer of stored procedures on top of database replicas as described here? Theoretically yes, but in practice no. In exactly the same way that you can theoretically service any car with only a set of mole-grips.
- camgunz 3y agoThis is just an interface, and you have the same problems with versioning and compatibility as you do with any interface. There's no difference here between the schema/semantics of a table and the types/semantics of an API. IME what data pipelines do is they implement versioning with namespaces/schemas/versioned tables. Clients are then free to use whatever version they like. You then have the same policy of support/maintenance as you would for any software package or API.
- slashdev 3y ago> There's no difference here between the schema/semantics of a table and the types/semantics of an API. There is a big difference. The types of an API can be changed independently of your schema.
- camgunz 3y agoYou're looking at the wrong layer. If we were to go to the layer you're talking about, we'd have internal and external tables where we could change the structure of the internal tables, and the rebuild/rematerialize the external tables/views from the internal ones.
- chedabob 3y agoYeah this is my gripe with things like Firebase Realtime Database. Don't get me wrong, the amount of time it saves is massive compared to rolling your own equivalent, but it doesn't take long before you've dug yourself a big hole that would conventionally be solved with a thin API layer.
- DrScientist 3y agoWhether it's method calls or database schema - isn't what really matters is control of what's accessible and the tools you have to support evolution? So when you provide an API - you don't make all functions in your code available - just carefully selected ones. If you use the DB schema as a contract you simply do the same - you don't let people access all functions - just the views/tables they need/you can support. Just like API's, databases have tools to allow you to evolve - for example, maintaining views that keep a contract while changing the underlying schema. In the end - if your schema dramatically changes - in particular changes like 1:1 relation moving to a 1:many - it's pretty hard to stop that rippling throughout your entire stack - however many layers you have.
- robertlagrant 3y agoYou can do impedance-matching code in a database, e.g. in stored procedures, but I think the experience is strictly worse than all the application-level tooling that's available.
- DrScientist 3y agoNot sure what you mean. Are you just taking about the expected shape of the data - the consumer of the database can do that either in SQL or at some later layer they control. If you are talking about my 1:1 -> 1:N problem. I'd argue that can ripple all the way though to your UI ( you now need to show a list, where once it was a single value etc ) - not something you can actually fix at the API level per se. Bottom line, the more layers of indirection, the more opportunities you have to transform - but potentially also the more layers you do have to transform if the change is so big that you can't contain it. Let's be clear - I'd typically favour APIs -especially if I don't control the other end. But I'm saying it's about the principals of surface area and evolvability, not really whether it's an API or SQL access.
- DasIch 3y ago> Just like API's, databases have tools to allow you to evolve - for example, maintaining views that keep a contract while changing the underlying schema. What are the database tools for access logs, metrics on throughput, latency, tracing etc.? Not to mention other topics like A/B tests, shadow traffic, authorization, input validation, maintaining invariants across multiple rows or even tables... Databases often either have no tools for this or they are not quite as good.
- moomin 3y agoI have spent my entire, long, career, fighting against someone who thought this was a good idea, unpicking systems where they implemented it or bypassing systems where this was implemented. It's a many-headed hydra that keeps recurring but rarely have I seen it laid out as explicitly as this headline.
- ignoramous 3y agoI guess that's what one gets for reading just the headline? TFA talks about the downsides called out in this thread explicitly. tbf, the idea isn't as novel. Data warehouses, for instance, provide SQL as a direct API atop it.
- moomin 3y agoI have, in fact, read the article, and they are _vastly underestimating_ the importance of those downsides. For instance, I once dealt with an issue that involved adding a column to a table, which they think shouldn't be too bad, that took two actual years to resolve because of all of the infrastructure built on top of it that bound directly to the table structure.
- DrScientist 3y agoBut surely the problem is with the infrastructure that can't deal with an extra column - not the db/table itself? If all the users of an API were bound to the shape of the data returned, but you wanted to add an extra field, you'd have exactly the same problem surely? Sounds like the problem was with too much magic in the layers above - as in the end the shape of the data returned from a query on a table is up to the client - you can control it directly with SQL - in fact dealing with an extra column or not is completely trivial in SQL.
- moomin 3y agoI mean, exactly, that’s why this is a bad idea. Adding a column is simple, having your DB be your API is madness. The more magic you add, the worse it gets.
- mattbrewsbytes 3y agoThe title reads like it came from an MBA biz-bro that doesn't want to do anything properly because it wastes time and costs money. FWIW, I skimmed the article. Building an API for a new application is a pretty simple undertaking and gives you an abstraction layer between your data model and API consumers. Building a suite of tests against that API that run continuously with merges to a develop/test environment will help ensure quality. Why would anyone advise to just blatantly skip out on solid application design principles? (clicks probably)
- camgunz 3y agoThe guy knows what he's talking about [0]. > Building an API for a new application is a pretty simple undertaking This is super untrue, backend engineering is pretty hard and complicated, and there aren't enough people to do it. And this is coming from someone who thinks it should be replaced with SaaS stuff like Hasura and not a manual process anymore. > Building a suite of tests against that API that run continuously with merges to a develop/test environment will help ensure quality. You can test your data pipelines too; we do at my job and it's a lot easier than managing thousands of lines of PyTest (or whatever) tests. > Why would anyone advise to just blatantly skip out on solid application design principles? Because building an API takes a lot of time and money, and maintaining it takes even more. It would be cool if we didn't have to do it. [0]: https://github.com/benbjohnson https://github.com/benbjohnson
- fatnoah 3y ago> If you give access to your DB directly, your API effectively becomes your API with all the contract obligations of the API. Suddenly you don't completely control your schema: you can't freely change it, you need to add things there for your clients only. I've seen it done multiple times and it always end up poorly. In a past life, I worked for a large (non-Amazon) online retailer, and "shipping the DB" was a massive boat anchor the company had to drag around for a long time. They still might be, for all I know. So much tech and infra sprung up to work around this, but at some point everything came back to the some database with countless tables and columns where no one knew the purpose, but couldn't change because it might break some random team's work.