26

I have RESTful API built on top of a MongoDB store, so it's nice that you can store arrays. It's straightforward to create a new resource like this:

POST /users { items: [ 1001, 1002, 1003 ] }

But how would the HTTP endpoint for adding a new item or removing an item would look like?

Right now, I have to specify the entire array, including elements that I don't want to touch:

PATCH /users/{id} { name: 'Bruce Wayne', items: [ 1001, 1002 ] }

Or pass in a mongodb query directly:

PATCH /users/{id}?query[$push][items]=1003

Is there a better way to do this?

Edit:

I like how StackMob's API does it. How do I update the name and remove an element from items at the same time though? For example, when I'm updating a bunch of the user's details on an admin dashboard? I don't think replacing the entire array is a good idea in mongodb?

thatmarvin
  • 2,800
  • 4
  • 22
  • 31
  • What are you using for the RESTful API? MongoDB doesn't have an out-of-the-box API that is intended for general use (it's for Admin's only). Further, it's not recommended for production use: http://docs.mongodb.org/manual/administration/security/#rest-api – WiredPrairie Mar 12 '13 at 20:16
  • I've clarified the question (there's an Express app on top of mongodb) – thatmarvin Mar 12 '13 at 20:36
  • For starters, I'd definitely avoid passing a mongodb query into a RESTful call. That can be a pretty significant security hole as someone could pass in an unexpected query that damages your data. – thehiatus Nov 07 '13 at 23:22
  • 1
    Are you asking how best to structure your API calls or how to perform mongodb queries that modify an entry instead of replacing the whole thing? – thehiatus Nov 07 '13 at 23:28
  • @thehiatus How to design the API endpoint on a high level, not the implementation details – thatmarvin Nov 07 '13 at 23:36
  • 5
    POST user/{id}/item/{item} for adding item to an array and DELETE user/{id}/item/{item} for removing item from array – Ravi Khakhkhar Dec 02 '13 at 09:39

2 Answers2

28

Passing a mongodb query seems like a bad idea. Depending on your backend implementation it could lead to an attacker doing bad things to your data as in SQL Injection

You can model the modification of an attribute on a resource with PUT or PATCH with some limitations:

  • When using PUT the client is expected to send the whole representation of the resource. IT works for you but it may be cumbersome.
  • When using PATCH the client is expected to send the attributes that are intended to change, instead of the whole resource. Yet, you have to send the whole value, not just the additions or deletions of items to the value. Again it works but you are not in love with it.

I think you are looking for a way to model adding and removing items to the array:

  1. I would model the array as a resource on its own: /users/:id/items
  2. Accept POSTto add an item to the array and DELETE to remove from the array.

It's simple and RESTful.

Daniel Cerecedo
  • 6,071
  • 4
  • 38
  • 51
  • 1
    The above methods is good, when working on a single item, either creation or deletion. How to structure the API, when I have to create/delete multiple items at once? – Saiteja Parsi May 03 '17 at 12:09
  • what if i have array items for user: { userId: 1, items: [1,2,3] } and just i want to remove "item = 2 & item=3"? In delee i can' set up "body". – Marek Woźniak Oct 15 '17 at 16:07
  • But you can identify items in the array by their index in the array used in the URI path `DELETE` `/users/:id/items/:index`. – Daniel Cerecedo Oct 15 '17 at 19:10
-1

As per the REST standards to create and delete a new request --> POST -Create a new resource in a collection and DELETE -Delete a resource

I can give you an example of how the high-level HTTP endpoint in java looks like using Jersey. You can have a Resource class with the HTTP Path specified and specific Paths for methods doing different operations. So the URL could look like -- /rest/MyResource/Resource accompanied by a request JSON or XML(that contains your input data)

Here is a sample Resource class that would be your entry point(ofcourse you would have to do your configuration in web.xml to do URL mapping for this class) -->

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.DELETE;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.json.JSONObject;

public class SampleRESTServiceResource {

    /**
     * @param incomingJsonString
     * @return Response 
     */
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response createNewResource(JSONObject myJson) {
        // Do a call to a DAO Implementation that does a JDBC call to insert into Mongo based on JSON
        return null;

    }

    /**
     * @param incomingJsonString
     * @return Return response 
     */
    @DELETE
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response deleteResource(JSONObject myJson) {
        // Do a call to a DAO Implementation that does a JDBC call to delete resource from  Mongo based on JSON
        return null;
    }
}

If you want to try out an example you can refer to this page --> https://www.ibm.com/developerworks/library/wa-aj-tomcat/

Prakhar Dixit
  • 151
  • 1
  • 1
  • 10
  • It's not addressing the question about high-level endpoint design for mongodb arrays, nothing to do with specific Java implementation. – thatmarvin Feb 23 '14 at 23:16
  • I thought it is specifically answering this question --> "But how would the HTTP endpoint for adding a new item or removing an item would look like?" So i gave an example of how it would look like in Java. – Prakhar Dixit Feb 26 '14 at 11:16
  • HTTP endpoint here refers to the specific HTTP method, URL and body content, like "POST /users" with body "{id:1, name:'John'}" – thatmarvin Feb 26 '14 at 21:13
  • that is what i have given my friend.. :) specific HTTP methods createNewResource(for POST) and deleteResource(DELETE) as endpoints in java (although i haven't given example of having content in body) .. – Prakhar Dixit Feb 28 '14 at 10:19
  • When we talk about methods in this context it is not Java methods or any language methods but HTTP Methods. Maybe that has been part of the confusion. – Daniel Cerecedo Nov 23 '15 at 11:50