I want to create custom rest api in magento, I tried calling it using tutorials available, but some how i am only able to call _retrieve and _retrieveCollection method only using GET.
So what I want to know how to create routes in api2.xml, so that i can call all the functions defined like:
_create
_retrieve
_delete
_update
_retrieveCollection
_multiCreate
_multiUpdate
_multidelete
and also want to know, when to use GET, POST, PUT and DELETE.
Any help is much appreciated.
So what I want to know how to create routes in api2.xml
Those other functions permissions are defined by the existence of for example <create>1</create> under the privileges for the role you want to use.
Once you've defined the privileges for your role(s), the routes depend on each type.
The easiest way (since the Magento API is not well referenced if you're adding your own things to it) is to look at existing core Magento code to see how they do it.
For example:
_create() is handled by the same endpoint as _retrieveCollection(), just use POST instead of GET. route_collection route. _create() uses the create privilege, while _retrieveCollection() uses the retrieve privilege.
_retrieve() is a GET request, defined as the route_entity route given the retrieve privilege
_delete() is a DELETE request to an entity endpoint (route_entity), given the delete privilege is granted
For multi examples, take a look for existing core code examples, e.g. _multiCreate(): Mage_Catalog_Model_Api2_Product_Website_Rest.
Related
Is there any way to specify custom paths for resources?
Example: <Resource name="User" path="/manageUsers" {...}>
If it's not possible "per resource", can we for example have all the CRUD pages be under a same basepath like: /crud/{/$resource.name} but keep the custom routes without that basepath.
Thank you very much.
EDIT #1
For context, we are building an admin panel that will have a lot of flows, basically step-by-step creation of resources. So I applaud the react-admin library for what it does (manage the CRUD part), but I want more flexibility in how the URLs are going to be.
I will need to have a section called /manageUsers/ that will have some data like a dashboard, and then the list could be /manageUsers/list/.
And then I may need another section called /customers/ that would list directly on that page.
EDIT #2
To give another use case, I'm trying to use graphQL as the dataProvider, and I had to rename all my resources since the rest API is using users where as the graphQL resource is User. So all my urls are now different!
I hope that makes it a bit more clear.
Is there any way to specify custom paths for resources?
No, this is not supported at the moment. One way to tackle this would be to use manageUsers as the resource name and translate it to User in your dataProvider.
I will need to have a section called /manageUsers/ that will have some data like a dashboard, and then the list could be /manageUsers/list/.
Definitely not supported by default either. However, you can replace the default Resource component with your own. It actually just creates routes for the resource inside a React Router switch. Note that you'll probably have to override the redirect prop of some components (such as Edit) because, when passed list, they expect the list to be at the resource root path.
I had to rename all my resources since the rest API is using users where as the graphQL resource is User
That's the dataProvider job to translate resources names into what your backend expect. Use resource names that make sense for your users (url wise).
I'm struggling to find an answer to this (perhaps because I'm not asking the question properly) ...
I'm building API to expose resources for a basic social networking service I'm creating.
My understanding is that the structure of URLs in an API is essentially a hierarchy, directory like structure. I think that means I can have multiple endpoints to reach the same resources or collections of resource links.
For example:
I have an endpoint
www.domain.api.org/users/{:uid}/posts
Which will return all posts sent by the user or that the user is tagged in. Seems ok, but what if I have an endpoint such as:
www.domain.api.org/posts
Which when hit with a http GET will return all public posts (i.e. all users' posts plus his friends' and public posts).
The difference is that the first URL points to user owned resources whereas the second to public ones (of which the users posts are included of course)
Are these okay or am I doing it the wrong / less sensible way?
To reiterate, can I have multiple endpoints which point to different contexts/views of the same resource?
Basically multiple endpoints for the same resources should be avoided. However in this particular case it does make sense.
What you can do is to introduce optional query param userId to the following endpoint:
www.domain.api.org/posts/?userId=<userId>
If this substitutes the first endpoint you mentioned that's the way to go.
I would like to add ontop of #Opal's answer.
Are these okay or am I doing it the wrong / less sensible way?
Ideally, like Opal mentioned, you would use queryParams in your url. For many applications I have build, I don't know the uids returned from the api beforehand, so selecting an item and passing it inside my url as a query parameter makes sense. But it also has the added benefit of having your key inside your url, allowing you to bookmark it, pass the url to another user and they will automatically see the same data you want them to see.
To iterate: Is your current implementation wrong? No, but ideally you would use a combination of both route parameters are query parameters to achieve this
To create an endpoints, you have to be sure that you have these information at once:
Name of the endpoint
Status: activate or not (required) - is the endpoint activated or disable
Service profile (required) - ID of the Service Profile assigned to the endpoint.
Tariff profile (required) - ID of the tariff Profile assigned to the endpoint.
You can add another optional informations, and be sure of the structure of your endpoint.
Hope this helps you.
This is a classic RESTful way of creating resources I have in the application:
# This creates user. Client is responsible to create UUID, which is simple
PUT /users/CLIENT_GENERATED_UUID
# Access user by uuid
GET /users/UUID
When we touch the field of data storage performance it turns out that randomly generated UUIDs do not serve well by many reasons like data locality.
Server-generated IDs are good for performance but they don't really match REST:
If you use POST to create resources, you lose idempotency: PUT, GET, DELETE idempotency is implied by REST, while POST is not.
You may ask server to provide you with a nice ID before doing PUT. Despite it feels quite heavy and non-obvious, it also does not protect from dummy client that uses own random id instead of asking for it.
Could somebody give me a hint in this architecture matter?
Creating a resource using is not meant to be idempotent. If the server assigns the ID, it must choose a different ID for every resource to be created. Such an operation must not be idempotent, repeating it must create a different resource.
Using POST against a collecton resource as in
POST /users
is totally RESTful if the server assigns the ID. This request can be repeated and it will create a different resource.
Using an idempotent operation like PUT for creating a resource only makes sense if the problem domain allows the client to control the ID. I think that is ist not true for most domains.
My advice: use POST and let the server assign the ID.
Actually when you read RESTful Best Practices you can find that:
The POST verb is most-often utilized for creation of new resources.
in addtion to:
PUT can also be used to create a resource in the case where the resource ID is chosen by the client instead of by the server.
In REST environment you send POST to create resources and can return the server generated ID to send the values after with PUT or PATCH.
POST /users
PUT /users/id
Also, people create resources with PUT using client generated IDs
PUT /users
But I think the best aproach is use server generated IDs with POST.
Here are a clear explanation: http://www.restapitutorial.com/lessons/httpmethods.html
I am new to designing REST APIs. I have trying to create following APIs for online game play
GET domain/api/games // return all games
POST domain/api/games // create a new game on behalf of current user
Now my issue is that when I try to create game using POST, I want userId to be sent to the API. I am not sure how to do this. Also note that I have another get API to get details of individual game, something like
GET domain/api/games/{gameId}
so I cannot pass userId to POST like domain/api/games/{useID} as it will conflict will above API.
So how do I pass usedId to POST. Also I don't want to use query params. Any suggestions to design this would be great.
When you are making a POST to a service, the parameters you communicate are known as BODY params, they don't go on the query string.
Different technologies have different APIs for interacting with POST params, but the underlying theory is the same, and is described by the W3C HTTP standard
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
The specifics of how to use POST params vary depending on the language and technology you're using. For example, if you are using jquery, there are a couple different ways to do it, with with the $.post('url', data, callback) method or with the $.ajax(...) option.
http://api.jquery.com/jquery.post/
http://api.jquery.com/jquery.ajax/
When reading POST params on the server, you'll generally access them using some some sort of request object, that will store your parameters in memory for you to access. This is highly dependent of the language and framework you're using, but here are links to some common ones:
NodeJS/express: http://expressjs.com/4x/api.html#request
PHP: http://php.net/manual/en/reserved.variables.post.php
ASP.Net: http://msdn.microsoft.com/en-us/library/system.web.httprequest.params(v=vs.110).aspx
Java/Spring: https://spring.io/guides/gs/handling-form-submission/
It should be either part of the context (you can pass it through header) or part of the game object. I prefer the context option, the httpheader can contain some auth bearer token so that you can figure out the user on the backend through the token.
I am trying to write a query in Ruby to insert a user story in Rally using WSAPI. I read through https://rally1.rallydev.com/slm/doc/webservice/.I looked it up and found that wsapi has a create() method, but I am not aware of its signature. I know it uses PUT/Post method for creation, but I just need an example to understand how to write create queries. Does anyone know of any useful resource to know more about this? I have all my code ready, just need information about writing "create" queries using Rally's WSAPI.
Thanks
There is a full directory of Ruby REST examples in the Github Repository for RallyRestToolkitForRuby:
https://github.com/RallyTools/RallyRestToolkitForRuby/tree/master/examples
This create example may be of particular interest. It's for a Defect, but the same logic would apply to Stories:
04-create-defect.rb