Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web API and Upserts

I'm working with Web API, and I'm trying to create an action that will perform an upsert.

I am passing in a user's first name and last name, and if that combination exists in my table, I want to update that user. If the combination does not exist, I want to create that user. (Yes, this is contrived, but for a blind wine-tasting party app I'm building, security isn't necessary)

Given that Web API has mapped POST and PUT to create and update operations respectively, it feels like there is a bit of friction here. I'm using the POST operation exclusively, should I be doing this in another way?

    // POST api/User
    [ResponseType(typeof(User))]
    public async Task<IHttpActionResult> PostUser(User user)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var current = await db.Users.FirstOrDefaultAsync(u => u.FirstName == user.FirstName && u.LastName == user.LastName);
        int id;
        if (current == null)
        {
            db.Users.Add(user);;
            await db.SaveChangesAsync();
            id = user.ID;
        }
        else
        {
            id = current.ID;
            //Do some updates
            current.Prop1 = "val";
            await db.SaveChangesAsync();
            user = current;
        }

        return CreatedAtRoute("DefaultApi", new { id = id }, user);
    }

The alternative, I suppose, would be to let the client decide whether it needs to do an insert or an update. That would necessitate another Web API call to determine an object's existence, and then consume the appropriate Web API with the appropriate HTTP verb.

like image 206
Mister Epic Avatar asked Dec 31 '13 18:12

Mister Epic


People also ask

What is upsert in API?

An upsert is a common technique that combines the automatic creation of a new record with an update to an existing record if it already exists using a single statement.

Should upsert be put or post?

The expected method for updating an existing record is PUT. So your choice should be PUT. So in your case you do not need any POST operation because PUT for upsert operation also covers that. Here the critical question about upsert is how likely you trust your client about upsert operation.

What is RESTful API?

RESTful API is an interface that two computer systems use to exchange information securely over the internet. Most business applications have to communicate with other internal and third-party applications to perform various tasks.


1 Answers

While there is no official standard, I'll give my two cents.

You should use PUT instead of POST for upserts. See this specification here.

PUT is used for idempotent operations or operations in which it doesn't matter if the request is sent multiple times the result will always be the same.

From the specification above:

If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.

Like I said, this is just my opinion. If you look at some other major RESTful APIs they do it differently. For example, the Salesforce REST API uses the PATCH method for upserts.

like image 118
jebar8 Avatar answered Oct 02 '22 04:10

jebar8