Method 'patch' already exists


#1

Hey All –

I may be going about doing this completely wrong so I’m open to all and any feedback. As background, I’m a BA/Product Manager and not an engineer who is trying to learn and work with RAML so I might be way off. I appreciate your patience!

What I’m trying to accomplish:
I want to document/show “intent-based” APIs. I have other details in the file and I’ve anonymized this but I’m outlining the main problem-statement first.

For example, I have a single method documented:

/resource:
    /{resourceId}:
        patch:
            displayName: updateResource()
            queryParameters:
                resourceStatus:
                    type: string
                    enum: [ active, cancelled, open, closed ]
     ...

This method is supposed to be a “generic” patch and pretty basic – good to go. Next I want to break it down and have an “API” specific for opening a resource, something like “openResource()”, and another for “closeResource()”, and so on. That way there is no ambiguity and if someone wants to open a resource, they call that API.

That ends up looking something like (the resourceStatus is pre-defined in types)…

/resource:
    /{resourceId}:
        patch:
            displayName: updateResource()
            queryParameters:
                resourceStatus:
                    type: string
                    enum: [ active, cancelled, open, closed ]

        patch:
            displayName: openResource()
            queryParameters:
                resourceStatus:
                    type: resourceStatus
                    required: true
                    default: open

Hopefully that gets across the idea.

The issue
Now I get a linter error – “Method ‘patch’ already exists”. It makes sense because, yes, it already exists. However, I want it to already exist!.

Am I crazy and trying to do too much in the RAML file? Should this be saved for implementation instead?


#2

Unless I am missing something, shouldn’t your openResource be a GET?


#3

I can see where it could be a POST but that just depends on how you’d want to implement. Think of it as “I want to open a resource” where “open” is similar to opening a box.


#4

The issue you are seeing is due to declaring patch twice for the exact same resource. You can not do that. What you would have to do is provide 2 query parameters for the one resource.

You are trying to shoehorn two different uses into the one resource. While that in itself is not really REST per se, you could use query parameters in a somewhat un-rest manner to indicate some action to take based on the query parameter provided.

I would suggest instead of query parameters, you use a request body, defined as RAML Type, for the first case… so that the body indicates the enum value to change (update). I would actually use the body for BOTH values that you are trying to pass as a query parameter.


#5

The various methods are nothing but a shared description of the function that you want the API (singular) to carry out.

In your example, which is very generic, it would appear at first glance that by “open” you probably mean “GET”, and by “update”, probably “PATCH”, though you can check this for yourself:

If this sounds like “mere semantics”, that’s because it is!


#6

So, by “open” do you in fact mean “create”, as in “let’s open a new case, inspector!”


#7

It’s interesting because this is how I had originally done it and a few engineers recommended using query parameters instead. I shall go back to what made more sense in the first place – a request body.

My main goal is to try and provide “intent-based” APIs. Basically the PATCH openResource is the same as PATCH updateResource() with a query parameter of ‘open’.

I know that is somewhat “non-RESTful” but… it makes more sense logically.


#8

“Open” is, somewhat, like GET. What I’m wanting to do is create an API that has a default query parameter but it is really just the same as the PATCH updateResource() API. The difference is the default parameter.


#9

Just found an entry in the forum that appears to express the same concern as what I tried to show in this thread.


#10

Sure, I don’t think your idea is bad per se, but maybe RAML is not the right tool? Or you could just add some of these custom items in the RAML doc fields?

The R in RAML standard for REST, and that framework comes with some basic assumptions. If you move outside of those definitions RAML may struggle to keep up, I guess?


#11

Thanks for the pointers @mhGLEIF. Annotations are another option and is intended for that kind of use cases too.