
Ask HN: Other than REST and GraphQL, what do you guys use? - palberg7
I&#x27;m building a web app and REST and GraphQL seem to be overkill for what I want to achieve. All I want is to get data for my React front-end and do couple of HTTP POSTs.<p>I&#x27;m thinking of simply creating express routes (I&#x27;m using Node.js) and using JSON but it seems cumbersome. Or is that a common practice?<p>I&#x27;m wondering what the alternatives to REST and GraphQL are.<p>Curious to know what y&#x27;all use for simple web apps.
======
ptttr
If you're looking for potential alternatives to REST and GraphQL, I suggest
checking out how Fulcro [1] works together with Pathom [2] using EQL [3].

It's a data-driven full-stack application programming system centered around
graph-based UI and data management implemented in Clojure [4].

While React lets you be declarative about your UI, Fulcro lets you be
declarative about your entire system - both backend and frontend.

Check out this discussion too:
[https://news.ycombinator.com/item?id=21743720](https://news.ycombinator.com/item?id=21743720)

[1] [https://fulcro.fulcrologic.com/](https://fulcro.fulcrologic.com/) [2]
[https://github.com/wilkerlucio/pathom](https://github.com/wilkerlucio/pathom)
[3] [https://github.com/edn-query-language/eql](https://github.com/edn-query-
language/eql) [4] [https://clojure.org/](https://clojure.org/)

~~~
palberg7
Interesting, thanks

------
ser0
If you all need to do is basic persistence and don't want to bother with
setting up your own backend, look into services such as
[https://restdb.io/](https://restdb.io/) or
[https://fauna.com/](https://fauna.com/) \- be careful about security if you
are embedding this in your front-end app.

Otherwise, writing your own backend using RPC-named express routes is more
than sufficient. The reason why REST became common is that RPC routes can
become messy.

Another poster gave the example of "SaveWidget" as an RPC endpoint. This can
cause problems for some teams that have no conventions and they end up with
"SaveFoo" and "BarSave" endpoints. REST solves this somewhat by relying on
HTTP verbs so both endpoints are normalised to "POST /foo" and "POST /bar".

Finally, if your web app is truely simple with only a couple of backend
endpoints needed, then whatever you choose is generally fine. Structural and
architectural patterns exist to provide a framework around managing
complexity.

If your app is not complex, most people - and it's important to consider this
includes your future self that has forgotten your implementation details - can
grok the codebase without too much trouble. If anything, as your question
suggest, over-engineering a simple app can lead to greater confusion.

~~~
palberg7
> services such as [https://restdb.io/](https://restdb.io/) or
> [https://fauna.com/](https://fauna.com/)

These are a no-go. Why should I use a proprietary solution when there are
superior free open source offerings? Sure it's more effort to spin up an aws
ec2 instance but that's very well worth it. I then have full control over my
database and I don't have to deal with proprietary sh*t.

> RPC-named express routes is more than sufficient

Yes RPC is exactly what I was looking for. It's super simple. I don't need all
that REST and GraphQL stuff.

> REST solves

Honestly, I don't understand what REST solves.

> over-engineering a simple app can lead to greater confusion.

Yes simplicity is key.

> RPC-named express routes is more than sufficient

Actually for Node.js there is Wildcard API[1] which I discovered yesterday.
It's even simpler than express routes.

[1]: [https://github.com/reframejs/wildcard-
api](https://github.com/reframejs/wildcard-api)

------
davismwfl
If you are building a simple web app, do you really need to separate it into a
different layer/call? Having a monolith isn't evil for simple apps, just have
a library or function you call to get the data and populate it server side. My
general rule is unless there are many separate types of clients (e.g. mobile
app, web app, backend services etc) needing the same thing, then it can just
be part of the primary application and returned server side. Lots of separate
client based calls are not necessary for a basic app (but some frameworks
kinda push you towards this). In fact, much of the time people would be better
putting a caching layer in first and returning the data with the server
render, at least initially until they have users and reasons to change.

Outside of that, yes, you can also just make it a route in the web app and
call it if you really want, nothing says it has to conform to a specific
standard. A simple HTTP get or post is good enough many times. GraphQL is also
overkill if you simply need to run a basic query.

~~~
palberg7
Yes that's what I want to do. Although I don't need caching (yet?)

~~~
davismwfl
Yea, sorry, that was worded a little poorly. My point was just from a monolith
you are smarter to add caching first before breaking it up anyway. So monolith
will get you to point A on the map, adding caching will usually get your
further to say point B, then finally you'll need to break the application
apart to scale further. That was my point.

Nothing evil about a monolith when you are starting out. I'd argue it is the
correct way to start out in fact.

------
iofiiiiiiiii
My preferred API design is RPC - expose various method calls to other systems.
In practice, this means gRPC whenever possible, basic HTTP RPC when not, and
finally SOAP is also fine if you are on a platform that has a sane
implementation.

I could try think of why but in practice, it just seems to work out the best.
Are there reasons? Sure. But coming up with a detailed rationale would take
some days of thinking. It just works very well.

This means on my service side I expose SaveWidget(id, body) ReadWidget(id)
PatchWidget(id, changes) QueryForWidgetsByFoo(foo)
QueryForWidgetsByFooBarAndSomeOtherSTuff(foo, bar, otherstuff) and on the
client side I just call them as if they were local (but rather slow
performing) functions.

Lots of little ifs and buts but this has proven the superior approach in all
scenarios where I control both client and server. I might go for REST for
wide-audience APIs just for the recognizability.

~~~
palberg7
Agree and that's exactly what I want to do. I want to define and call
functions as if they were local. I control both client and server.

For Node.js there is [https://github.com/reframejs/wildcard-
api](https://github.com/reframejs/wildcard-api)

------
status_quo69
Rest is (simplified) just a way of expressing your routes as resources. If you
want to post and get some things that's perfectly fine but you'll probably
wind up accidentally fitting into a different paradigm (rpc for example if you
start naming your routes getFooBar and newFooBar).

You can also post form data instead of json if you think json is overkill but
getting data from the server is probably limited to something like json unless
you want to decide on a custom format or your data is truly so simple that you
can just return a single text blob.

~~~
palberg7
> Rest is (simplified) just a way of expressing your routes as resource

What is the benefit of doing that? RPC seems much "better" than REST.

------
silviogutierrez
Possibly inflammatory, but not only are REST or GraphQL overkill. They're
outright _wrong_ for many domains. If you are not exposing your service to
others, this is especially true.

Look at any mature framework (Django, Laravel) and either use that or emulate
it.

Why?

REST and GraphQL deal with discrete resources. yes, GraphQL can deal with
many, but it's still an abstraction to group calls.

In my experience, I'm dealing with user input that _does not map cleanly to
resources_. Ultimately, if you persist things, of course resources are
affected. But the input is its own world.

The sign REST/GraphQL abstractions are breaking is when you create ad-hoc
endpoints/entry-points to serve these resources.

Classic example would be a call to "copy 5 widgets from Y category to Z
category".

In resource-oriented world, you could do:

1\. PUT/POST for each widget, changing the category label sending the full
resource.

2\. Or you could write an ad-hoc endpoint that accepts more than 1 widget,
repeat as above.

3\. You still need to figure out the "proper" way to handle the category. If Z
doesn't exist, do you make them PUT/POST to /categories/ to create one first?
Or do you auto create it for them? How do you auto create it? Does the
category field accept the primary key of a category _and_ arbitrary text in
case you're creating a new one? That's odd.

4\. So on and so forth.

How would I do it in Django world, at least?

1\. Create a view, it will have 2 forms on the view and process them together.

2\. Form 1 is a formset with a row per widget you wan to copy. Any number of
rows can be sent. Django will validate they are valid widgets.

3\. Form 2 is a form with a "from_category" and a "to_category" as well as a
"new_category_name".

4\. Form 2 has a validation rule, if to_category is null, new_category_name
must have a label for a new category.

5\. In the view, process Form 1 and 2 together, if valid, handle a create
everything.

The difference is subtle. But you're decoupling input from resources. I yearn
for an API-centric way to do this.

~~~
palberg7
Thanks that made a lot of sense.

------
lgl
> I'm thinking of simply creating express routes (I'm using Node.js) and using
> JSON but it seems cumbersome. Or is that a common practice?

Yes, it's common practice. As for being cumbersome, as cumbersome as creating
conforming ReST or GraphQL endpoints? Keep it simple I'd say.

~~~
palberg7
True it's still much less cumbersome.

------
alexfromapex
Flask is a pretty simple REST API to setup that is relatively performant

~~~
palberg7
What do you think of FastAPI?

~~~
alexfromapex
Looks to be pretty similar but it may be better for asynchronous applications
since it runs on ASGI. The only thing I would be hesitant about is sometimes
with newer frameworks it takes them a while to gain maturity and a robust
collection of plugins and community support.

------
lukasfischer
JSONAPI, we use Drupal a lot, and Drupal 8 comes with JSONAPI out of the box.

