atomicdata-dev / atomic-server

An open source headless CMS / real-time database. Powerful table editor, full-text search, and SDKs for JS / React / Svelte.
https://atomicserver.eu
MIT License
953 stars 44 forks source link

Nested requests - GraphQL (or similar) support for server side rendering / headless CMS features #251

Open joepio opened 2 years ago

joepio commented 2 years ago

The graphql API is pretty popular, and for good reason. Most importantly for me, it allows nested resources in one request. This means you can populate a list of blogposts and include their authors and their profile pictures without needing round-trips. These round-trips are a problem when doing server side rendering, which is quite essential if you want jamstack style applications using CDNs for amazing performance.

I think it should be possible to add a graphql endpoint to afomic-server. Some approaches:

Full GraphQL with async-graphQL

Note that we can't use derive macros from any GraphQL crate, as the data models are not known at compile time!

Issue about not using derive.

(compared to juniper, it has more features)

https://github.com/async-graphql/async-graphql

Even supports actix

https://github.com/async-graphql/async-graphql/tree/master/integrations

Minimal example

https://github.com/async-graphql/examples/blob/6a16d2f5d5eeb56e0b2989ed8bc4b061ecd74ca3/actix-web/starwars/src/main.rs

Full GraphQL support with Juniper

https://docs.rs/juniper/latest/juniper/trait.GraphQLType.html#

GraphQL-like support

Instead of supporting all of GraphQL, we could choose to only support a very strict subset - one that is lightweight, and therefore easier to maintain and to implement.

{
   "@id": "https://example.com/someResource",
   members,
}

HTTP headers

We can construct a JSON object that represents the nested query and pass that as an HTTP header:

X-Atomic-Nested = {jsonfield}

{
  "members": {
    "author": {
      "profilephoto": {},
      "friends": {}
    }
  }
}

Alternatively, we could describe a list of paths like so:

["members.author.profilephoto", "members.author.friends"]

Or as nested arrays:

[["members", "author", "profilephoto"], ["members", "author", "friends"]]

Deepr

Similar to graphQL: https://github.com/deeprjs/deepr

JSON-LD Frames

JSON-LD with empty objects to denote that it should be filled in

https://w3c.github.io/json-ld-framing/

joepio commented 1 year ago

@AlexMikhalev