Check whether a category name is available. API dry-run / custom slug?

I’m facing an issue where I need to check wether creating a category with a given name is possible with the API — in other words, if a category slug is not already taken.

Right now, I check it by fetching /c/foobar.json and interpreting it (404 means available).

User wants to create Foobar (slug foobar) → checking if /c/foobar.json already exists

But if the user wants to create Foo Bar (slug foobar too) it will raise an error because the slug already exists from another category (Foobar).

I’d need either:

  • To call an endpoint made for that (e.g. /category-available/name.json) but I think it’s too specific.
  • To specify the slug as a parameter of the category creation endpoint.
  • To dry-run the API category creation process. This could be extended to other creation endpoints.

What do you guys think?

If a category name is taken, sending a POST request to /categories.json returns an error message:

{"errors":["Category Name has already been taken"]}

You could check for this error message.

3 Likes

In the creation process of my application, creating a Discourse category isn’t the only step. Therefore, to avoid being in a inconsistent state, I prefered not to try to create a category to check wether the name is available or not.

To be specific, I also create a GitLab project derived from the same name the user is giving. What if the Discourse category slug is available but not the GitLab slug? The Discourse category would be created but not the GitLab project. Sure I could remove the just-created category in that case, but that’s a lot of spilled electricity :wink:

You’ll probably always have to handle problems while creating the category. The name already being taken is not the only possible reason for this to fail, and the category could be created after you checked whether the name is taken :slight_smile:

Sure, but I’d need to handle the “name already taken” error specifically in terms of UI/UX. Other errors would not be user-related (because the only thing that ties my user to Discourse at this point is a category name) and would be treated as server errors.

Yes, but checking it by issuing a POST request to categories.json would automatically create it if available, not only check it :confused:

That’s what I meant in:

Sorry, that’s not what I meant. Even if you did check whether the name already exists, later on, creating a category might still fail simply because someone else has created the category in the meantime.

Good point. But then I’d treat it like a server error.

My point being: I cannot test wether a category name is already taken or not without having side-effect (trying to create the category) or do it unreliably (trying to fetch the category with the slugged name — slugged with another library than the Discourse’s one so maybe not the exact same slug in some conditions, therefore making the test irrelevant).

Can’t you just check categories.json?

2 Likes

I’d have the same problem with trying to fetch /c/{slug}.json. I can’t reliably predict what slug will be produced from a given name, other than running it through the Discourse Slug module, which is only possible by creating a category and check the output. But then, side-effect. That’s why I’m looking for a side-effect-free way to check the availability of a category name/slug.

Otherwise, I see that I can in fact choose a slug when creating a category but it’s not documented, and the check wether a category name is available or not is done on the name and the slug. Is there a good reason to do so? In my case, most of the categories would be hidden and only accessible from direct link, so it’s not a big deal if multiple categories have the same name (but different slugs).

That’s not what I recommended – can’t you check /categories.json instead?

We’ll get there :smiley:

You recommended to check /categories.json for the existence of a category name/slug is that right ?

If so: I can’t check a name and its slug because I can’t predict what slug will be produced from a given name without…

Possibly stupid question, because I didn’t check, but…
If you don’t specify a slug, doesn’t Discourse automatically select a free one?

You’re right, but I just saw that in fact Discourse doesn’t allow duplicate category names even with different slugs.

I can indeed check if the category name is already present in /categories.json, but what about string cleaning, escaping, and such? I can’t be 100% sure the name given by the user in my app front-end will be the same as the one Discourse would use when creating the category.

Example: Would 🎹 Category with an emoji appear as so in /categories.json or will the emoji be stripped? If not now, I can’t be sure it won’t be the case tomorrow. Depends on so many factors, from the app to the server.

The only way I can be sure is to feed Discourse this name and get the response. As of today, the only way is to try to create it, and therefore having side-effect.

My feature proposal still stands :slight_smile: It would be great to have a side-effect free way to check if a category name is available.

Allowing duplicate category names (restricting unicity to slugs) is another request.

Slight correction here - the full list of categories and subcategories is actually at /site.json .

2 Likes