brillout / wildcard-api

Functions as API.
MIT License
368 stars 14 forks source link

@defer & @stream #34

Closed brillout closed 4 years ago

brillout commented 4 years ago

Follow up of https://github.com/reframejs/wildcard-api/issues/10#issuecomment-589241713

cc @johnson544

Today, something like @defer can be done with Wildcard by doing:

// Browser

const {endpoints} = require('@wildcard-api/client');

const highPrioData = await endpoints.getHighPrioData();

// We defer heavy and non-important data

const lowPrioData = await endpoints.getLowPrioData();

With callback arguments you'd be able to implement streaming and further defer optimizations:

// Browser

const {endpoints} = require('@wildcard-api/client');

const newsItemsStore = {};

// Streaming:
// (Can also be used to defer)

endpoints.getNewsItems(function(newsItems){
  newsItems.forEach(item => {
    newsItemsStore[item.id] = item;
  });

  renderWithReact(newsItemsStore);
});

I am also based in Germany. If you want to chat more about it we can schedule a call :-)

Gerne :-) Write me on Twitter (https://twitter.com/brillout) or email me (github@brillout.com) and I'll give you my WhatsApp number.

a side node: What I really like in graphql is fetching certain fields from a type. I feel a helper function that deals with pagination and over-fetching would be also very cool. something like https://github.com/spatie/laravel-query-builder

The idea with Wildcard is to directly use SQL/ORM queries; with Wildcard, you can simply use the pagination tools of your database.

There is no over-fetching problem with Wildcard as you can write your enpdoint functions to return only and exactly what your frontend needs. For example:

// Node.js server

const {endpoints} = require('@wildcard-api/server');

const Todo = require('./path/to/your/data/model/Todo');

// Get all (and only the needed) data for the landing page.
endpoints.getLandingPageData = async function() {
  const todos = await (
    Todo
    .select(['id', 'text'])
    .find({userId: this.user.id, completed: false})
  );

  return {
    user: {
      name: this.user.name,
    },
    todos,
  };
};
yosbelms commented 4 years ago

There is no over-fetching problem with Wildcard as you can write your enpdoint functions to return only and exactly what your frontend needs.

That is the problem, you need to write a new endpoint for each front end needs. So, your endpoints will be organized by view use case, not by resources. So yes, there is an over-fetching problem.

Another well known is the N+1 queries.

Let's suppose you have an endpoint to retrieve a list of bank accounts, and another one to find a client by ID. I you need a view showing a list of account ID including the name of the owner (client), you need to create a new endpoint to fit the requirements, otherwise, perform a HTTP query to get the list of accounts, and a HTTP query for each account to get the client. This is called N+1 queries.

Anyway, Wildcard API is intended in a different way, it binds server and client side transparently. But reading endpoints and API in the docs inevitably makes me to compare to modern API tech around which to overcome the issues mentioned by @Johnson444

brillout commented 4 years ago

I'd agree with you if you need to minimize the number of endpoints, which makes sense in a scenario were the server can only be deployed every two months while the frontend is redeployed every day. In that case you shouldn't use Wildcard and you need a generic API such as REST or GraphQL.

But if you develop and deploy backend and frontend hand-in-hand, then you can go the opposite way: one endpoint per frontend need. You can then simply wrap each SQL/ORM query your frontend needs in an Wildcard endpoint. Wildcard is then just a thin security layer on top of SQL/ORM. In that case you don't have any over-fetching nor N+1 problem

yosbelms commented 4 years ago

@brillout Exactly, I got (I suppose) the Wildcard concepts quickly, but some developers interested in the project not yet. So, I think that docs can be more explicit in the way Wildcard in intended to be used, and highlight the approach differences with other client-server solutions out there, also some recipes, and how to avoid N+1 and over-fetching issues, achievable with Wildcard if we applying the traditional client-server -API, endpoints- mindset.

I think it is sane to avoid words like API, and endpoints, which brings comparison under that concept, although, I suggest to use concepts such as bridge, link, direct which can bring an idea of a transparent direct layer.

Summary, I think it is just about education. What do you think about this?

brillout commented 4 years ago

You are very right, what we just discussed has been a recurrent misunderstanding (and miscommunication on my part) about Wildcard (and RPC in general).

Adding educational material to elucidate the differences between RPC and APIs is very much something I'm interested in doing.

I've actually searched for an alternative name to "Wildcard API" in order to get rid of the "API" word. Ideas?

I'm curious; are you currently using Wildcard? How long have you been using it?

yosbelms commented 4 years ago

I've been only assessing Wildcard, but I realized what is this project about and how it fits in the current library ecosystem.

About the naming I'm not good at it 🤣 BTW I'm the author of Remote Func which actually I think it deserves a better name.

PD: we are getting offtopic

brillout commented 4 years ago

Interesting what you are doing with Remote Func. What was your motivation to write it?

I've been thinking about adding a Schema add-on to Wildcard for scenarios where the server is set in stone and/or there are many clients and only one server. With something I call "object-level permissions" to handle authorization. You'd then have the best of both worlds.

yosbelms commented 4 years ago

What was your motivation to write it?

I don't get the Idea behind "object-level permissions", we can discuss it in a new thread.

brillout commented 4 years ago

Closing in favor of https://github.com/reframejs/wildcard-api/issues/61.