Components vs Schemas Implementation

Was looking for some clarification on best practices for implementing components vs schemas. Take the ERD example below.

In this example I have two definite schemas. First, the homepage which is a single content schema because I want to allow the editor to edit the content on the homepage. Second, is the Link, because I want this piece to be shared for SEO purposes. This way links with the same name will always have to point to the same url. It also allows me to add inline editing for the editor role on the list since there will likely be multiple names for the same href tag.

What I’m trying to decide is the best practice for the next three pieces shown in gray.

First we have the ProductCategorySection which is an array in the homepage. ProductCategorySection of course will have Products (or in this case ProductCarouselItem), and a product item will have a UniversalImage (which is a simple definition of image and string today for simplicity of the question, but will likely have more fields)

What I’m trying to understand better here in this example is what makes the most sense from a squidex implementation?

Should components inherit other components? Should most things be a schema? etc… What makes the most sense from just a performance standpoint outside of having a reusable component thats part of a schema and not directly editable?

To give you a further example, taking the example above I could set up the following…

Basically in this case universal image is a component because its uniqueness does not matter and a general editor is not important. ProductCarouselItem inherits this as a field and it is a multi-content schema because it will get used in multiple pieces and being able to share it across schemas would be useful. ProductCategorySection relates directly to a page and is not shared, so it could be a component.

Anyways, I know this is a new feature, and I just thought it would be helpful to get some clarification on how you saw components vs schema usage so we can take the right steps for long term implementation.

Also, side note, as this is my first support ticket, I just wanted to thank you for building Squidex. We actually tried an implementation of Strapi before Squidex, and going to Squidex has been like finding water in a desert. The difference in code standards, UI, performance and just in general ability to search past support issues in the forum is significantly better. I really appreciate the time and effort you’ve put into this project.

2 Likes

First of all: thank you very much for your nice words. Just spread the words.

About your problem:

I would actually make it totally different. The advantage of components is that they can be rearranged and dynamically added. When you think about the homepage you might want to change the contents very often and make changes. Therefore it makes sense to have a structure like this:

  • Headline
  • Subheadline
  • Components

The component can then be one of multiple components:

  1. Text
  2. ProductCategoryTeaser

For both components you have two alternatives and it might make sense to have actual bother.

** Alternative 1**: A component is just a reference to another content, e.g. an article or ProductCategoryTeaser.
** Alternative 2**: A component is self contained and contains all necessary data, e.g. the list of products.

Components are always part of the content iself, so they do not have any negative performance implications, but references need to be resolved. Fortunantely Squidex is clever enough. When you resolve references through GraphQL it makes one additional call per level. So if you content has 20 references from 10 different schemas it is only one database call. If you you need 5 contents and each content has 20 references it is also only one database call.

I hope you get what you mean. What tool do you use? I can also make a diagram it if the tool is free.

Thanks for the quick reply

I use a tool called lucid chart, which is free for minimal use. You can see my original diagram at https://lucid.app/lucidchart/5899e0b9-3027-4074-8e07-c663eba974dc/edit?invitationId=inv_a8e06e92-1bc2-4993-9cb9-0b26b0b073eb

I think I get what you are saying, but I may be off base. Its interesting hearing about the performance. I guess this is one of the big advantages to going the nosql route vs sql. Interestingly enough I originally partially asked this question because I noticed a component broke down in edit mode at about 3 levels on Friday, but it looks like this is now fixed, and you can go down 1 to n levels, which is pretty awesome.

So to sum it up, what I think you’re saying is…

  1. A component created in schema mode can be used to essentially be a private schema added to an existing schema for a singular db reference. In other words the component is now editable only in the schemas that use it, and an api call for content will now return the schema data and component data in the same call. GraphQL requires multiple calls still (side note, even though this may be true, it does return a flatter json return structure than doing flatData each time you access a reference).

  2. A component/components added as a field in a schema can be tied to either a component or schema, and essentially gives you inline editing within the schema in editor mode. This can go 1 to n levels. This piece is singular to the schema being edited, so the data added here will not be shared with other schemas that may use a reference field.

Your example of the homepage being a headline and just random set of components was what I was originally shooting for with Strapi and started to move away from. Its great to see we can do that here, I think I’ll move in this direction again.

One quick note, I noticed I could also add a component I created as a reference field. This appears to work in the editor, but I noticed it doesn’t seem to translate well in GraphQL.

Hope I got this right, either way the explanation was helpful and have given me some confidence to use components more often from a performance standpoint.

Thanks.

A schema is structure describing the fields. Because we do not use SQL, a schema does not mean a table. Any schema can be used as component and it means: When you create content for this field it must follow the structure described by the schema. You can also mark a schemas as component when you create it, which just means that you cannot create content directly for it.

When a schema is used as component structure it is always flatten. The reason is that I do not want localized components in localized fields as it becomes super complicated.

From the GraphQL perspective there should not be that many differences from components vs references, but the implementation is different of course.

1 Like

thanks for the awesome information.

1 Like