-1

I have to create a service which expose an API (REST). It will use MongoDB as a database and structs as data model. The problem is I really can't find a nice solution for making the basic CRUD non repeatable. For example:

I have 3 struct (ModelA, ModelB, ModelC) Each serves as a model for a db document. I have to expose an API where user can add, edit, list and delete documents. Also with pagination and filtering. I've made a handlers for each API urls. Lets say the urls for managing each model are:

  • /model_a/{:id}
  • /model_b/{:id}
  • /model_c/{:id}

If I call GET /model_a/ it should list all ModelA documents. Also I can pass some arguments to filter the list. If I call GET /model_b/ it should do the same but for ModelB documents. The code for two handlers is basically the same. And I want to simplify it a little bit.

I was trying to make some generic methods with interface{} as an argument to which I can pass a variable of model type. Here is simplified example:

func (r *Routes) GetHandler () {
   var model models.modela
   r.GetList(&model)
}

func (r *Routes) GetList (m interface{}) {
   ...
}

But it generates a lot of problems and I really feel that this is not the correct approach. Also this way I loose the advantages of struct type to which JSON should be marshalled.

I've spend a lot of time on researching and I can't find any good example on how to write an API with multiple structs. All I've found (even in books) is how to make handlers, http listener and such stuff. But this is what I know. I need to learn how to design something bigger than simple API.

If someone knows where I can find such knowledge or anything that could help me understand a little bit better correct approach in designing good API in Go I would appreciate that.

  • 2
    You keep telling us about the tools you want to use (REST, MongoDB, Go, JSON). You haven't said one word about what your service is supposed to do. Why is your service different from anyone elses? Hint, the answer has nothing to do with your tools. – candied_orange Aug 16 '17 at 1:43
  • @CandiedOrange I don't know if my service is different. All examples I've found led me to the very repeatable code, just like I mentioned. And I think its important that I'm using Go because, in for example Node.js, approach would be different. The service is going to manage user projects in database for Web application that I'm writing. So it will consists of many models and CRUD for that models. In most cases, code will be the same or very similar for each model. However, I do want to rely on structs in Go, not maps like map[string]interface{}. – mkatanski Aug 16 '17 at 8:58
  • 1
    There isn't enough adequate information in your question to make it answerable. You haven't even told us what the problems this approach generates are. – Robert Harvey Aug 21 '17 at 19:08
1
+50

I am making an assumption that you would be interested in providing a RESTful interface to different domain objects which are stored in a Mongo DB database.

From a RESTful design perspective, CRUD operations correspond to different HTTP methods. Eg:

GET /person

Gets list of all Person objects from the database (Mongo DB)

GET /person/{id}

Fetches just one Person object from the database

PUT /person/{id}

Updates (idempotent operation) a Person object in the database for the specified ID

DELETE /person/{id}

Removes the record of Person object with the specified ID

POST /person

Creates a new record and returns the Person object with an ID associated to the record in DB.

Because you are looking to not duplicate effort in writing code over and over again for similar operations on different Model objects. I think having a look at APIs like https://spring.io/guides/gs/accessing-mongodb-data-rest/ would give you a declarative way to program. All you have to do is create an interface with the Model you want the RESTFul API to expose and the framework takes care of generating implementations to that interface.

Thus eliminating the need for broiler-plate code. I would encourage you to leverage the support that Spring provides for RESTFul web services(I am not into Go! Maybe there is support for Go too!)

Keep us posted on how the research goes and we might be able to help further.

  • in fact, there is something like goa. github.com/goadesign/goa. I think i will give it a try. Thanks for pointing me to the better solution. I wanted to achieve it using native tools but i guess its the best aproach right now to use goa. Thanks. – mkatanski Aug 25 '17 at 14:11
0

You could create a service S (which will expose the REST API), using Go and structs. Then, you could create a module M, which receives/retrieves JSON, and internally uses MongoDB.

You could perform all specifics for each type within S; the CRUD within module M can be implemented seamlessly since it uses JSON, therefore no need to repeat code.

What is unclear to me is what stuff you need within your service apart from the CRUD. Perhaps with more information we could provide a better answer.

-2

Have you known Graphql? This solution handle data operation API. I think it help you to save effort and reduce the repeated code.

protected by gnat Aug 22 '17 at 4:56

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.