Search code examples
apirestapi-designmodeling

API modelling: Two resources with the same name


I have an API modelling question I need help with.

Let's assume I have Product representation that consists of:

Attribute Type
id string
names MultilingualName List
price decimal

MultilingualName is represented by:

Attribute Type
locale string
name string

This is to support multiple languages, so that a store owner user is able to create products (and maintain/CRUD) within a product shelf that supports multiple languages.

Our POST API (/products) may look like this:

{
    "id": "123abcxyz"
    "names": [
                {
                    "locale": "en-CA",
                    "name": "Pencil"
                },
                {
                    "locale": "fr-CA",
                    "name": "Crayon"
                }
             ],
    "price": 1.99
                         
}

The problem I am having trouble with is with the consumer user based GET end point for Product.

I would like to model the resource without having the MultilingualName language complexity. So for example, the GET endpoint would look like this:

Attribute Type
id string
name string
price decimal

The end point would return the product name based on the user's preferred language, which is already known.

But clearly I have a problem. I have two Products resources now: CRUD operations (GET, POST, PUT, DELETE) geared to the store owner that maintains their product shelf (with the language complexity), and one for the consumer user (GET only, without the language complexity).

How should I approach this model? Is this a naming problem or am I approaching the modelling incorrectly?

Thanks for your help.

Edit: adding a UML as suggest by @qwerty_so. API Model UML diagram


Solution

  • Remark: answer provided when question had an UML tag (last part still valid though)

    Multiple problems in your diagram:

    • An actor is a classifier that is external to the system. A class can therefore not be associated with an actor.
    • A «use» dependency should be noted with a dashed line arrow, and not a plain line arrow.
    • It is not clear what the links between your «Representation» classes and you »«DB table» represents: is it again a dependency? Is it a navigable association?
    • You have multiple definitions of a name without any possibility to disambiguate.

    How to do it in UML?

    In UML, having two classes with the same name in the same namespace is not valid, since it would not be clear which class is meant.

    Nevertheless, you could adjust your model and separate the different family of classes, enclosing them in distinct packages, e.g. Database, CRUD, Consumer.

    A package defines a namespaces. In consequence all references to a Product in the CRUD package would refer to the relevant CRUD class.

    For relations between classes of different packages, you may disambiguate with a qualified name (i.e. including the package names), or, in case there would be no conflict, by importing a package into another.

    Is it the best way to design your API?

    Managing conflicting names in endpoints is not ideal. It’s n easy source of confusion. You can of course find technical solutions to address this, but still, why bother ?

    Why not leave the client side tailoring/simplifying data as needed (e.g. using the user's language by default, unless something else is required)?

    Why not let the end-point query parameters provide an optional language code to filter the set of returned languages ?

    Or why not just use different names to call differently different things? I was thinging about ProductLocalized or ProductShort?