bdunogier / ezplatform-graphql-bundle

GraphQL server for eZ Platform, the open source Symfony CMS.
13 stars 6 forks source link

Implemented domain content #3

Closed bdunogier closed 6 years ago

bdunogier commented 8 years ago

Allows query of content using their identifier and fields directly. The content types groups are used as root, with the content types as leafs. It can be accessed at /graphql/domain and /graphiql/domain.

{
  content {
    articles {
      name: title { text }
    }
    folders(query: { Text: "HTML" }) {
      name { text }
    }
  }
  media {
    images {
      name { text }
      image {
        large_image: variations(identifier: "large") { uri }
        small_image: variations(identifier: "large") { uri }
      }
    }
  }
}

It relies on a Custom GraphQL types for ContentTypes of the Repository, such as ArticleContent or BlogPostContent. Those have GraphQL fields for values of their fields values, allowing very quick access to actual content items values: Those types also have a _content field that gives access to the underlying content item.

The schema for those is generated using a Command script. When executed, it writes the schema to src/AppBundle/Resources/config/graphql.

TODO

janit commented 8 years ago

Works great for a pile-of-content and takes out the complexity of knowing how complex field types like Image and RichText work internally as they're exposed easily.

Here are some comments:

bdunogier commented 8 years ago

I would expect the query {domain} to resolve to a list of types by default, instead of error

I'm not sure we can do that. If it is an object, and it is if you have dumped the domain schema, then you need to select something from it.

Term "domain" is not descriptive and potentially conflicting to example.com, foobar.com...

It is a term that has been around in our, well, (engineering) domain. As in Domain Driven Design. Maybe there are better alternatives, but this one is pretty solid imho (ping @andrerom). Naming is hard :)

This works for a pile of content, but not if I want to leverage the location tree. Would it be possible to add search options for location or is mixing objects/locations like oil/water?

We can do plenty of things. About location(s), what would you expect in regards to those ? I was thinking that the UrlAlias was maybe an important property.

Is it feasible to have the schema update dynamically when adding / modifying items in the future?

Complicated, we're gonna have to dig: the yaml schema is compiled in the container.

janit commented 8 years ago

I would expect the query {domain} to resolve to a list of types by default, instead of error

I'm not sure we can do that. If it is an object, and it is if you have dumped the domain schema, then you need to select something from it.

Ok, I am just trying to think how this would be as consistent as possible. Actually now comparing to {location}, {content}, {user}... the behaviour is consistent, but {domain} contains the error message, which made me think it works somehow else. So this is fine.

Term "domain" is not descriptive and potentially conflicting to example.com, foobar.com...

It is a term that has been around in our, well, (engineering) domain. Maybe there are better alternatives. Naming is hard :)

Naming is hard, for sure as in this case there's already content and contentType. Maybe concatenate this to contentTypeDomain?

This works for a pile of content, but not if I want to leverage the location tree. Would it be possible to add search options for location or is mixing objects/locations like oil/water?

We can do plenty of things. About location(s), what would you expect in regards to those ? I was thinking that the UrlAlias was maybe an important property.

Ideally I would like to mask the concepts of objectand location from the casual API consumer, who might not be familiar with eZ at all. If they would start with this API and not be limited to content searches, I would like them to have basic access to location search capabilities:

I think this more thought and better specification, but simply not to cause immediate frustration / if you would like to tap into locations in addition to content. Locations are a key feature in eZ Platform that many CaaS services (including Contentful) do not have.

andrerom commented 8 years ago

Cool to see protoype of this, get it a bit better now. But shouldn't this align with concepts in API? And if this needs custom mapping, I still think some form of native domain types might be better for this then having to map up things manually here tough (somewhat like what was attempted to be introduced here: https://github.com/ezsystems/ezpublish-kernel/pull/955/files).

bdunogier commented 8 years ago

But shouldn't this align with concepts in API?

Well, I'm not sure. The Repository's API is covered by the initial GraphQL implementation (content, location, etc). I see this approach as one level aboveIt could be a Site API approach, even though for this we need an intermediate layer (like what netgen has done). But being given PHP objects structured after the Content's type is kind of what is done in the User/UserGroup prototype is it not ?

andrerom commented 8 years ago

But being given PHP objects structured after the Content's type is kind of what is done in the User/UserGroup prototype is it not ?

?

bdunogier commented 6 years ago

The PR has been rebased to make more sense. See the new syntax in the PR's description.

Ideally I would like to mask the concepts of objectand location from the casual API consumer, who might not be familiar with eZ at all. If they would start with this API and not be limited to content searches, I would like them to have basic access to location search capabilities:

folders will list folders, but can be provided with an extra query. That extra query will accept location based criteria, such as ParentLocationId:

{
  content {
    folders(query: {ParentLocationId: 2}) {
      name { text }
    }
  }
}

Details about the location can be accessed using the _ properties: _location (main), _allLocations (as well as _content for the content item itself).

bdunogier commented 6 years ago

Note: I intend to merge this very soon. It is getting tedious to maintain it.

1 or 2 reviews would be appreciated.

bdunogier commented 6 years ago

I'm now prototype something about children. To get a tree of all folders, as well as the titles of the articles they contain:

content {
  folders {
    name { text }
    _children(mainLocationOnly: false) {
      ... on ArticleContent {
        title { text }
      }
    }
  }
}

By default, it loads all children from all the content's locations. The idea is to have a mainLocationOnly option, as well as a Subtree option. Other ideas to work with multiple locations are welcome. It could also be made recursive. It will use the search service for filtering anyway.

The _children property will only show up for containers.

bdunogier commented 6 years ago

Ping @andrerom @janit, and other people you think would have interest in this.

janit commented 6 years ago

I'll take a look this week, as I'll also need to try how #17 works :)

bdunogier commented 6 years ago

I'll take a look this week

Thank you, I really appreciate. In any case, I intend to merge it soon, because:

I'd say we are fairly safe.

as I'll also need to try how #17 works :)

It works really well ;)

Some more work is needed to provide support custom field templates arguments. There's also a grey area when it comes to custom templates, as we currently don't have a way to provide custom parameters to html.

bdunogier commented 6 years ago

I'm merging this, for the reasons explained in this comment.