// bad var errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';
// bad var errorMessage = 'This is a super long error that was thrown because \ of Batman. When you stop to think about how Batman had anything to do \ with this, you would get nowhere \ fast.';
// good var errorMessage = 'This is a super long error that was thrown because ' + 'of Batman. When you stop to think about how Batman had anything to do ' + 'with this, you would get nowhere fast.';
messages = [{ state: 'success', message: 'This one worked.' }, { state: 'success', message: 'This one worked as well.' }, { state: 'error', message: 'This one did not work.' }];
length = messages.length;
// bad functioninbox(messages) { items = '<ul>';
for (i = 0; i < length; i++) { items += '<li>' + messages[i].message + '</li>'; }
return items + '</ul>'; }
// good functioninbox(messages) { items = [];
for (i = 0; i < length; i++) { // use direct assignment in this case because we're micro-optimizing. items[i] = '<li>' + messages[i].message + '</li>'; }
// bad // make() returns a new element // based on the passed in tag name // // @param {String} tag // @return {Element} element functionmake(tag) {
// ...stuff...
return element; }
// good /** * make() returns a new element * based on the passed in tag name * * @param {String} tag * @return {Element} element */ functionmake(tag) {
// bad functiongetType() { console.log('fetching type...'); // set the default type to 'no type' var type = this.type || 'no type';
return type; }
// good functiongetType() { console.log('fetching type...');
// set the default type to 'no type' var type = this.type || 'no type';
return type; }
给注释增加 FIXME 或 TODO 的前缀可以帮助其他开发者快速了解这是一个需要复查的问题,或是给需要实现的功能提供一个解决方式。这将有别于常见的注释,因为它们是可操作的。使用 FIXME -- need to figure this out 或者 TODO -- need to implement。
使用 // FIXME: 标注问题。
1 2 3 4 5 6 7
functionCalculator() {
// FIXME: shouldn't use a global here total = 0;
returnthis; }
使用 // TODO: 标注问题的解决方式。
1 2 3 4 5 6 7
functionCalculator() {
// TODO: total should be configurable by an options param this.total = 0;
Edition 5 clarifies the fact that a trailing comma at the end of an ArrayInitialiser does not add to the length of the array. This is not a semantic change from Edition 3 but some implementations may have previously misinterpreted this.
// good /** * parseInt was the reason my code was slow. * Bitshifting the String to coerce it to a * Number made it a lot faster. */ var val = inputValue >> 0;
Only use nouns in your resource URLs, avoid endpoints like /addNewUser or /updateUser . Also avoid sending resource operations as a parameter. Instead explain the functionalities using HTTP methods:
GET Used to retrieve a representation of a resource.
POST Used to create new resources and sub-resources
PUT Used to update existing resources
PATCH Used to update existing resources. PATCH only updates the fields that were supplied, leaving the others alone
DELETE Used to delete existing resources
9.3 Use sub-resources
Sub resources are used to link one resource with another, so use sub resources to represent the relation. An API is supposed to be an interface for developers and this is a natural way to make resources explorable. If there is a relation between resources like employee to a company, use id in the URL:
GET/schools/2/students Should get the list of all students from school 2
GET/schools/2/students/31 Should get the details of student 31, which belongs to school 2
DELETE/schools/2/students/31 Should delete student 31, which belongs to school 2
PUT/schools/2/students/31 Should update info of student 31, Use PUT on resource-URL only, not collection
POST/schools Should create a new school and return the details of the new school created. Use POST on collection-URLs
9.4 API Versioning
When your APIs are public for other third parties, upgrading the APIs with some breaking change would also lead to breaking the existing products or services using your APIs. Using versions in your URL can prevent that from happening: http://api.domain.com/v1/schools/3/students
9.5 Send feedbacks
9.5.1 Errors
Response messages must be self descriptive. A good error message response might look something like this:
Note: Keep security exception messages as generic as possible. For instance, Instead of saying ‘incorrect password’, you can reply back saying ‘invalid username or password’ so that we don’t unknowingly inform user that username was indeed correct and only password was incorrect.
9.5.2 Align your feedback with HTTP codes.
The client and API worked (success – 2xx response code)
200 OK This HTTP response represents success for GET, PUT or POST requests.
201 Created This status code should be returned whenever a new instance is created. E.g on creating a new instance, using POST method, should always return 201 status code.
204 No Content represents the request was successfully processed, but has not returned any content. DELETE can be a good example of this. If there is any error, then the response code would be not be of 2xx Success Category but around 4xx Client Error category.
400 Bad Request indicates that the request by the client was not processed, as the server could not understand what the client is asking for.
401 Unauthorized indicates that the request lacks valid credentials needed to access the needed resources, and the client should re-request with the required credentials.
403 Forbidden indicates that the request is valid and the client is authenticated, but the client is not allowed access the page or resource for any reason.
404 Not Found indicates that the requested resource was not found.
406 Not Acceptable A response matching the list of acceptable values defined in Accept-Charset and Accept-Language headers cannot be served.
410 Gone indicates that the requested resource is no longer available and has been intentionally and permanently moved.
The API behaved incorrectly (server error – 5xx response code)
500 Internal Server Error indicates that the request is valid, but the server could not fulfill it due to some unexpected condition.
503 Service Unavailable indicates that the server is down or unavailable to receive and process the request. Mostly if the server is undergoing maintenance or facing a temporary overload.
9.6 Resource parameters and metadata
Provide total numbers of resources in your response
The amount of data the resource exposes should also be taken into account. The API consumer doesn’t always need the full representation of a resource.Use a fields query parameter that takes a comma separated list of fields to include:
1
GET /student?fields=id,name,age,class
Pagination, filtering and sorting don’t need to be supported by default for all resources. Document those resources that offer filtering and sorting.
9.7 API security
9.7.1 TLS
To secure your web API authentication, all authentications should use SSL. OAuth2 requires the authorization server and access token credentials to use TLS. Switching between HTTP and HTTPS introduces security weaknesses and best practice is to use TLS by default for all communication. Throw an error for non-secure access to API URLs.
9.7.2 Rate limiting
If your API is public or have high number of users, any client may be able to call your API thousands of times per hour. You should consider implementing rate limit early on.
9.7.3 Input Validation
It’s difficult to perform most attacks if the allowed values are limited.
Validate required fields, field types (e.g. string, integer, boolean, etc), and format requirements. Return 400 Bad Request with details about any errors from bad or missing data.
Escape parameters that will become part of the SQL statement to protect from SQL injection attacks
As also mentioned before, don’t expose your database scheme when naming your resources and defining your responses
9.7.4 URL validations
Attackers can tamper with any part of an HTTP request, including the URL, query string,
9.7.5 Validate incoming content-types.
The server should never assume the Content-Type. A lack of Content-Type header or an unexpected Content-Type header should result in the server rejecting the content with a 406 Not Acceptable response.
9.7.6 JSON encoding
A key concern with JSON encoders is preventing arbitrary JavaScript remote code execution within the browser or node.js, on the server. Use a JSON serialiser to entered data to prevent the execution of user input on the browser/server.
If the request type is POST, provide a working examples. URL Params rules apply here too. Separate the section into Optional and Required.
Success Response, What should be the status code and is there any return data? This is useful when people need to know what their callbacks should expect!
1 2
Code: 200 Content: { id : 12 }
Error Response, Most endpoints have many ways to fail. From unauthorised access, to wrongful parameters etc. All of those should be listed here. It might seem repetitive, but it helps prevent assumptions from being made. For example
There are lots of open source tools for good documentation such as API Blueprint and Swagger.
10. Licensing
Make sure you use resources that you have the rights to use. If you use libraries, remember to look for MIT, Apache or BSD but if you modify them, then take a look into licence details. Copyrighted images and videos may cause legal problems.