I'm working on REST Api suing Python Flask, as I have more and more routes, its hard to manage all the resource urls.
Right now, I'm confused which one is better practices of URL parameters. Examples below:
Get a list of courses with limits:
/courses/<int:lim> OR /courses/list?lim=10
Get a specific course:
/courses/<code>/<section> OR /courses/show?code=cs100§ion=1
Get a list of students in specific course:
/courses/<code>/<section>/students OR /students/show?code=cs100§ion=1
Should I pass query parameters using / or by doing ?
The only reason I'm using / is that there's no conflict in query.
If I have these two URL for two different queries, how can I fix it so I can query base on the parameters:
/students/show?code=cs100§ion=1 (Get all students in that course)
/students/show?id=123456789 (Get the specific student)
The URL should identify a resource or collection of resources. Any options you want to give the client, such as pagination, limits, filtering, sorting, etc. I think is best to include in the query string or in HTTP headers.
So regarding your specific questions:
Get a list of courses with limits: /courses/<int:lim> OR /courses/list?lim=10
Neither one. Use /courses?lim=10. No need to have a /list component, that is an action, not a resource.
Get a specific course: /courses/<code>/<section> OR /courses/show?code=cs100§ion=1
The first. Once again, /courses/show indicates an action, you want URLs to be links to resources, in this case your course.
Get a list of students in specific course: /courses/<code>/<section>/students OR /students/show?code=cs100§ion=1
The first, same reason as the previous one.
I have given REST API talks at the last two PyCon conferences, feel free to check them out if you want to learn more API design best practices:
PyCon 2014: Writing RESTful Web Services with Flask
PyCon 2015: Is Your REST API RESTful?
Related
I've just started looking at the documentation as we are going to need to integrate Salesforce with Social Tables shortly, so I am really new to Social Tables.
Specifically, we will need to sync data between the CRM and Social Tables Events and Guests, and maybe other objects, so it would be very helpful to have a data model or similar to check the relationships and fields available in Social Tables architecture.
I haven't found anything in the documentation, is there any way to get this, even if it's at a high level?
Thanks
Danny
To make an integration with SocialTables you'll have to do a few manual steps, there is no way to do this completely programmatic from my experience. You'll also have to be prepared to contact SocialTables to get get correct guestlist ids. Also keep in mind that the API documentation isn't always correct, the API logic is also quite difficult to understand from time to time.
The first thing you need to do is figure out which version of the Venue Mapper you use. You'd want to use the 4.0 api and as far as I know this version of the api is only supported by Venue Mapper 3.0. I believe the Venue Mapper 3.0 is the frontend tool SocialTables provides to do the venue planning.
In social tables an event has two ids, one numerical one and one alpha-numerical one, when you use the 4.0/events endpoint you only get the alpha-numerical event id, and your going to need the numerical one. The only way I've been able to get the numerical id is to pull it out from the url when using the Venue Mapper, example of the url follows below:
https://plan.socialtables.com/team/{team_id}/event/{event_id}/space/{space_id}
Now you need to get the guestlist id, you can get that by using the following url, using the numerical event id:
GET https://api.socialtables.com/4.0/diagrams?event={numerical_event_id}
This endpoint return a json structure where one of the parameters is "guestlist_id".
Please be aware that the guestlist id you get from this endpoint might not be the correct one. I struggled quite a bit with this part and ended up with SocialTables sending me the guestlist id by email.
To get the guests in your guestlist use the following api endpoint:
GET https://api.socialtables.com/4.0/guestlists/{guestlist_id}
The {guestlist_id} is an alpha-numerical string similar to: cfdac1c0-yb1d-12e6-84a5-a39e92131645
And by that you should hopefully get access to your guests.
Hey thanks for using our API.
To answer your question, the best way to see the data model at the moment is to access our developer portal and use the API console to see what is returned. For events you will need to know the team id of the team you are working with use the team events endpoint to get access to the event ids.
https://developer.socialtables.com/api-console#!/Events/get_4_0_legacyvm3_teams_team_events
This will return some basic information about each event for that team. You can then request additional details for specific events by using this endpoint:
https://developer.socialtables.com/api-console#!/Events/get_4_0_legacyvm3_events_event
When designing a restful API, resource ownership is a consideration when designing the URIs. In my case, I'm working on an API where two of my entities will be people and addresses. Each person can have more than one address, so in the database they'll be in separate tables.
Normally I just use auto incrementing keys, so each new record adding increases the ID number.
A thought I had was that if I uses this approach, it would effectively produce a URI like this:
/people/11/addresses/52
In that case, person 11 doesn't have 52 addresses. It's just person 11, who has an address with an ID of 52.
The other side of it is whether I would even be using a URI like that. Addresses generally won't be retrieved on their own by the client, but as part of a person object retrieved by a single API call (/people/11 would retrieve all addresses associated with that person).
Anyway, I guess the question here is about best practices. Is it common to see an entity owned by another with ID values like that? What are the general practices with this?
Your method is correct.
Also These are general rules (reference):
- An API is a user interface for a developer - so put some effort into making it pleasant
- Use RESTful URLs and actions
- Use SSL everywhere, no exceptions
- An API is only as good as its documentation - so have great documentation
- Version via the URL, not via headers
- Use query parameters for advanced filtering, sorting & searching
- Provide a way to limit which fields are returned from the API
- Return something useful from POST, PATCH & PUT requests
- HATEOAS isn't practical just yet
- Use JSON where possible, XML only if you have to
- You should use camelCase with JSON, but snake_case is 20% easier to read
- Pretty print by default & ensure gzip is supported
- Don't use response envelopes by default
- Consider using JSON for POST, PUT and PATCH request bodies
- Paginate using Link headers
- Provide a way to autoload related resource representations
- Provide a way to override the HTTP method
- Provide useful response headers for rate limiting
- Use token based authentication, transported over OAuth2 where delegation is needed
- Include response headers that facilitate caching
- Define a consumable error payload
- Effectively use HTTP Status codes
Also there are lots of references on web. This page is a good start.
and these are also useful: slide1, devzone tutorial
You would normally use a resource like: /people/11/addresses/52 when you return the details of an address in a personalised manner for the people entity.
If for example, you have entities: people and office which can have addresses, and for people you want to display only the country and for offices you want to display all the details of addresses.
On the other hand, if you don't need customization you can also use an url like: /address/12 , since it will be easier to cache a response like that.
Addresses generally won't be retrieved on their own by the client,
but as part of a person object retrieved by a single API call
(/people/11 would retrieve all addresses associated with that person).
If this is the case you can leave out the detailed addresses url.
Yes, That's correct way to apply many to many relation in APIs. Just remember to check id2 belongs to id1 when returning the value.
For retrieving all the addresses the correct call is /people/11/addresses. Then you know you have to call a join query.
I have an android application connected to magento server by rest api. The application must preform some actions, but I have no examples of requests needed for the application.
For example I have this list of requests, but it is superficial enough for my application. For example, I do request:
"http://myUrl.com/api/rest/products?limit=15" and receive the list of 15 products. But after I need to receive next 15 product, and next, and next... What request can do it?
Also I need to do another requests which have no in site examples.
Where can I get more information and examples about rest api requests? Thank You in advance.
You can use various get filters available for REST request in magento GET FILTERS. To access second page you can use page filter available i.e. "http://myUrl.com/api/rest/products?limit=15&page=2". You can also combine many filters and use them as you want. Eg. For getting a result of products which have their name like 'product123', you can use: magentohost/api/rest/products?filter[1][attribute]=name&filter[1][like]=%product123%.
I'm building my first REST API (at least trying) for a personal project.
In this project there are resources called players which hold can be in a team. According to REST API design rulebook a resource should be made either to be a document or a store and one should keeps these roles as segregated as possible.
Yet I would like to append some metadata to the team resource, eg the date the team was founded. Is it okay then for GET /teams/atlanta to return this metadata (making it a document) alongside the list of players in the team (making it a store).
Is this a good idea? If so why? If not why not and how to solve this better?
I know there are no rules to developing a REST API, but there are good practices and I would like to adhere to those. Please also not that this is really my first REST API so pardon my ignorance if there is any.
I would recommend having GET /teams/atlanta return just the information about the team, such as the founding date that you mention, and then having GET /teams/atlanta/players return the list of players for that team. These distinctions become more important when you are presenting an API that uses HTTP methods other than GET.
For example, if you wanted to add a player to a team - this would be a lot easier if you could just POST a player object to /teams/atlanta/players than if you had to PUT the whole team object to /teams/atlanta every time you wanted to add one individual player.
If your API only allows retrieval of data, and if it is for a specific client application, there is an argument for combining all the team data into one object to save the client having to make additional requests for the data, but bear in mind that it is less flexible.
Your application may want to display a list of teams by calling GET /teams but you probably wouldn't want all of the player information included in each object in the list as this is quite a lot of data, but if GET /teams/atlanta returns player information then it would be inconsistent not to include it in the list version too.
I would personally favour splitting up the resources as I've suggested, and live with the fact the client may need to make an extra request or two.
I've been reading a lot and I understand that a REST API maps resources with HTTP verbs. That's very easy of understand when, for example, a tutorial show an example like Employee.
A PUT will be a new record (if it doesn't exist) or an update; a GET will extract a list with all employees, and a GET api.example.com/employee/12 will extract the record for the Employee with ID = 12.
But, for example, how I could map a more useful queries like "get me all the employees with a salary under 50.000, with less that 2 years at the company and with the marital status as single"?
In other words, how I could parametrize the query? Is it correct to add parameters like api.example.com/Employee?salary<50000&years<2&marital-status=single" ?
The theory:
If you add parameters to your query, they are just part of the URL. The form of the URL does not tell you anything about whether your API is RESTful. Your API with query strings is restful if it obeys the constraints described here: http://en.wikipedia.org/wiki/Representational_state_transfer and (optionally) follows the guiding principles
So as long as your query parameters don't do anything crazy like randomly change the state of some of the resources, then your API is still RESTful
The practice:
Any sensible REST API will need query parameters for the 'index' route. In practice, LinkedIn's REST API has query parameters that just select fields from someone's profile. In this case, the URLs looks completely different from yours, but still obey the principles of REST.
Your situation:
Your query strings can't contain inequalitites, only key+value pairs. You need to express it more like ?max-salary=50000&max-years=2&marital-status=single". You might also name your 'index' route differently: api.example.com/employees (plural)