Api error api unavailable

Installous API Error

Installous-Error
Используя приложение Installous, некоторые пользователи сталкиваются с ошибками, периодически выдаваемыми программой. Часто происходит, что ошибки сопровождаются полным отказом работы Installous. Сегодня мы рассмотрим ошибки API (API Error).

API Error – API unavailable
Ошибка приложения – «недоступный API» означает, что программа Installous не может обратиться к серверу Apptrackr.org. Для тех, кто не знает, Apptrackr это сетевая версия Installous, которая позволяет загружать IPA-файлы непосредственно на Ваш настольный компьютер.

API unavailable
Причины возникновения ошибки:
•   Слабый сигнал точки доступа Wi-Fi
•   Ваш поставщик услуг Интернета заблокировал доступ к сайту Apptrackr, таким образом, оградив Вас от неофициальных приложений
•   Сервер Apptrackr перегружен, т.е. временно не доступен из-за большого количества посетителей.

API Error – Permission denied
Ошибка приложения – «Доступ запрещен» означает, что ваш IP-адрес был заблокирован представителями Apptrackr. Блокировка может временной или постоянной. Блок может быть вызван многочисленными запросами к Installous API

Permission denied
Действия пользователя:
•   Если используете динамический IP-адрес, подождите 24 часа, после чего работа возобновится
•   Если используете статический IP, то можете узнать свой IP-адрес при помощи любого сервиса, к примеру whatsmyip.org, и обратиться с просьбой о разблокировке на форуме Apptrackr

Запись опубликована в рубрике ИНСТРУКЦИИ с метками Installous, iPhone игры. Добавьте в закладки постоянную ссылку.

Things don’t always go well when making your first API call, especially if you’re a beginner and it’s your first time integrating an API into another system. Often documentation is lacking in terms of api error status codes, since it’s easier to anticipate things going right, rather than things going wrong.

HTTP status codes can give you an idea of what was going on when you made your API call. The standardized status codes go from 100 to 511, and all have different meanings, but only the status codes from 400 to 511 reflect an error response. If you’re using Moesif, see a summary of the most likely API error status using this handy table.

Let’s look at the 10 most common HTTP status codes that indicate an error response, either on the client or the server-side.

Client-Side Status Codes

The 4XX group of status codes is usually related to client-side errors, but changes to the API can also cause them. Here are the 5 most common client-side status error codes and how to solve for them:

404 Not Found

This is by far the most common HTTP status code you can get. It indicates that the URL you used in your request doesn’t exist on the API server, or origin server. While this is a 4XX error, which usually means something on the client-side is wrong, this can also indicate a server problem. Sometimes API URL paths change after a version update, but sometimes they change because something on the server went wrong.

The best course of action is to check if you have a typo in your client code before checking if the API has issues.

This status code means you haven’t yet authenticated against the API. The API doesn’t know who you are and it won’t serve you.

For most APIs you need to sign up and get an API key. This key is then used inside an HTTP header field when you send a request, telling the API who you are.

This http status code is similar to the less common 407 Proxy Authentication Required, which means you haven’t authenticated with the proxy.

403 Forbidden

The forbidden status indicates that you don’t have permission to request that URL. You’re authenticated, but the user or role you’re authenticated for isn’t permitted to make the API request.

This also occurs when you have an authentication issue, like when using the wrong API key or trying to access features your subscription plan doesn’t allow for.

400 Bad Request

The 400 Bad Request error message is one of the most generic HTTP status codes. It implies that you did not correctly format your API request. If no additional error information is given in the response body, you have to check the docs. You could be missing a query, a field in the request body, or a header field could be wrong. It could also be that some of your request data might have incorrect syntax.

This is different from the 422 Unprocessable Entity error message, which appears when your request is correctly formatted, but cannot be processed.

429 Too Many Requests

Most API subscription plans have limits — the cheaper the plan, the fewer requests per second are allowed for your API key.

If you’re sending too many requests in a short amount of time, consider throttling them in your client. This response can also indicate that you hit a daily, weekly, or monthly limit on your account. Without implementing API analytics, it’s possible to reach these limits without receiving a push notification or email alert.

Sometimes an API sounds like a right fit until you see the limits, and suddenly it doesn’t work for your use case anymore. Check what’s part of your API subscription before integrating, otherwise you may run into problems weeks or months after integrating the API.

Server-Side Status Codes

The 5XX group of status codes usually return in response to a server error, but an invalid API call that should respond with a 4XX can also return a 5XX error if not caught correctly on the server. Here are the 5 most common errors and how to fix them:

500 Internal Server Error

This HTTP status code can mean anything really, but it usually indicates the API server crashed. It could have been caused by something related to your API call.

Double-check the docs to make sure you did everything right: query fields, body fields, headers, and format.

If that didn’t fix the problem, it might also have been related to an API update that introduced buggy code, or data the API loaded from an upstream service. In that case, your only cause of action is contacting the API’s support.

502 Bad Gateway

This response tells you that the server you were calling wasn’t the actual API server, but a gateway or proxy. The proxy server tries to call the API server in your name. This error response also indicates that the API server didn’t answer. This could be related to a network problem, or simply because the API server crashed, or was down for maintenance.

A “bad gateway” error is usually temporary and should be solved by the API provider, but you have to contact support if it persists.

503 Service Unavailable

The 503 Service Unavailable Status indicates a server error. Too many API requests were sent and now the API can’t handle any more of them. This problem solves itself when clients send fewer future requests, but it could also mean that the API provider didn’t plan enough resources for all of its customers.

If it fits your use case, you can make your client more resilient to this error by waiting to send another request. But if the error code keeps showing up, you have to contact the API provider.

504 Gateway Timed Out

Like the 502 Bad Gateway status, this response code tells you that the server you were calling is a proxy for the real API server. This time, the problem is the API server’s slow response.

This could be related to high network latency between the proxy and the API server. It could also mean that the API server takes too long to process your request.

To solve this problem, check if your request’s content could be related to that timeout. If you are requesting too much data or a calculation that takes too long, you should try and reduce it.

If you think your request is reasonable and the status doesn’t go away, contact support.

501 Not Implemented

The 501 Not Implemented status code is related to the HTTP method you used to request an URL. You can try a different HTTP method to make the request.

Usually, an HTTP request with an inappropriate method simply results in a 404 not found status. A not-implemented status implies that the method isn’t implemented “yet.” The API creator can use this status to tell the clients that this method will be available to them in future requests.

Monitoring HTTP Status Codes With Moesif

Moesif provides a rich set of monitoring and notification capabilities, so you can keep abreast of any HTTP status code errors automatically and gain deep insights from your error response trends.

Dashbaords showing 4xx and 5xx error trends

API calls are always tracked with user identity, so it’s easy to locate errors and solve them rapidly.

Automatic altering for status codes

Summary

Undoubtedly you’ll see many error codes when using APIs, but most have reasonable fixes. Some are related to server errors and some to client-side errors, where often one can cause the other.

Always try to read the docs and API notes thoroughly, so you don’t forget something while integrating. If things are simply broken, contact the API provider.

In some cases, the API provider won’t ever fix an issue for an API consumer. If you’re using a popular API you can also search the web for answers, especially StackOverflow, to find a fix for your error responses. Stay determined, and you’ll see your 200 ok status codes in no time.

Debug And Fix API Issues Quickly With High-cardinality API Logs

Learn More

Kay Ploesser

Kay Ploesser

Software Engineer and Web Enthusiast

I keep getting this error:

API Error: EspoCRM API is unavailable.
Possible problems: disabled «mod_rewrite» in Apache server, disabled .htaccess support or RewriteBase issue.
Do only necessary steps. After each step check if the issue is solved.

None of the suggested fixes work. PHP configuration is all OK. I have tried with the last three versions of EspoCRM, up to the July 27, 2018 version.

Apparently the address to the API is wrong. What should the address be? What is the script getting? Is there an error log with more info somewhere? How do I troubleshoot this?

I am trying to install EspoCRM in a folder on an add-on domain on a VPS, like this:

website.com/crm

which is actually a rewritten (?) version via virtualhost and dns magic of:

website.maindomain.com/crm

I think the assumption is that you install EspoCRM in the www root (/var/www/html). Is there any way to get EspoCRM to work in a folder of an addon domain? What changes should I make?

I see this problem has been reported before, but I can’t find a solution anywhere.

Adding an API Gateway to your application is a good way to centralize some work you usually have to do for all of your API routes, like authentication or validation. But like every software system, it comes with its own problems. Solving errors in the cloud isn’t always straightforward, and API Gateway isn’t an exception.

What is AWS API Gateway?

AWS API Gateway is an HTTP gateway, and as such, it uses the well-known HTTP status codes to convey its errors to you. Errors in the range of 400 to 499 usually point to a problem with the API client, and errors in the range of 500 to 599 mean something on the server is wrong.

This is a rule of thumb, and if you don’t have any logic bugs in your backend, it holds. But nobody is perfect, and so it could happen that a 400 code still means your client is right and your backend is wrong. But let’s not get ahead of us and look into the errors, case by case.

what is aws ap gateway

Handling API Gateway 400 Error: Bad Request

The 400 error is probably the broadest of the client errors. Depending on what AWS service API Gateway is integrating with for the URL, it can mean many things.

A retry usually doesn’t help because it means the request doesn’t match what that specific API Gateway integration is expecting, and sending it again wouldn’t change that.

Reasons for this error include:

  • Invalid JSON, like missing commas and such.
  • Missing fields, when the upstream service has required a field you missed
  • Wrong data types, when you send a string instead of a number
  • Invalid characters, like using whitespaces in identifiers

You can find the required fields, expected data types, and valid characters for a field in the documentation of the AWS service you integrated with API Gateway.

Handling API Gateway 403 Error: Access Denied

This error is also known as “Forbidden” and implies some permission issue. Every resource you provision in AWS has an IAM role. This role defines what that resource can access and how it can access it. Your API Gateway has an IAM role too, and if it’s not configured correctly, it can prevent API Gateway from integrating with a service.

Again, a retry doesn’t help here.

If you use end-user authentication with AWS Cognito, every request will get a temporary role related to the Cognito user who issued the request. If this role isn’t configured correctly, it can also prevent users from accessing specific resources.

If you’re using a custom Lambda authorizer in your API Gateway, this error code could also relate to a problem in that Lambda function.

Handling API Gateway 404 Error: Not Found

The 404 error usually means your URL is wrong. Probably in 99% of the cases

If you’re sure the URL is right, but you’re still getting the error, it could also be related to the service you integrate with API Gateway when you try to access data in these services that aren’t there.

A retry only solves this problem if the 404 comes from a race condition. When you told the backend to create a resource, you wanted to access it with the next request, but the request was too soon, and the thing you created isn’t there yet. Such issues happen with eventually consistent data stores like DynamoDB. 

The more expensive consistent reads of DynamoDB usually solve this problem.

Handling API Gateway 409 Error: Conflict

The 409 status indicates that your request is trying to do something that conflicts with a resource’s current state. A resource could be a record in a DynamoDB table that’s integrated with your API. It could be that you tried to create a resource with a specific ID that already exists.

The 409 error is also related to something called a callers reference. This reference is used to mark a request, so it gets only executed once. If you send it and don’t get an answer from the API, you don’t know if the request got lost before or after it made its way to the API. This usually leads to a retry. If the API hasn’t seen the caller reference the last time, it will simply execute it and respond with an appropriate status code. But if the API has seen the caller reference, it gives you a 409 status code to indicate your request was already accepted when you sent it the first time.

So, a retry usually won’t solve this problem and can even be the source of this error code in the first place.

Handling API Gateway 429 Error: Limit Exceeded

There are two 429 errors you could get from API Gateway. The first one is called “Limit Exceeded Exception,” which indicates that you went over an API quota.

API Gateway allows access control via API keys. When creating such a key, you can also define a usage quota such as 1000 requests per week. If this quota is reached, the API gateway will respond with a 429.

Normally a retry doesn’t solve this problem. You either have to increase the quota for the key, or you have to wait until the next usage period starts.

The best way to get around this issue is to keep your API requests monitored and counted. Check how many requests you send and if you really need to send so many. You can also try to cache responses so that you can reuse them instead of sending duplicate requests that count to your key’s quota. 

Handling API Gateway 429 Error: Too Many Requests

The second 429 error is of temporary nature. You would get it if you sent too many requests at once. For example, if you have an API endpoint connected to a Lambda function, this function has a predefined limit of 1000 concurrent invocations.

If you send 1001 in parallel, you get a 429 error, but depending on the time this Lambda function takes to handle a request, you can retry some time later and get a free slot again.

Again, API keys can have limits too. If you got a key that only allows for 10 concurrent requests, the upstream service could handle millions, but your 11th parallel request wouldn’t go through.

Try to monitor your request so you see when they get close to the limit of your services, and try to cache requests on your clients so that they won’t hammer the API.

api gateway detecting issues

Did you know Dashbird will detect API Gateway issues and alert them to you?

Handling API Gateway 500 Error: Internal Server Error

The 500 status code might be the most used and most generic HTTP error on this planet. If you get it from an API endpoint that integrates with AWS Lambda, it usually means your code buggy.

The next source for this error is inconsistent error mapping. Many of the errors we talked about here can become a 500 error when finally landing on your client as a response. You’ll get a “limit exceeded,” but it will have a 500 status code instead of 429. So you have to extract the right error out of this response, check what the real cause is, and then look at how to solve it.

Since the error can be anything really, a retry can technically solve that problem, but usually, it doesn’t.

If you monitor your system carefully and get one of these every few million requests, it could be that cosmic rays flipped some bits or whatever. Still, if you see a 500 status code more often than that, it’s crucial to investigate; it can very well point to an inconsistency that will blow up sooner or later.

Handling API Gateway 502 Error: Bad Gateway

A 502 error code is related to the service your API Gateway integrates with. It means that API Gateway couldn’t understand the response.

For example, when you throw an error in a Lambda function or the resolved value has an invalid structure, it can lead to a 502 error. If you used EC2 or ECS/EKS, it could also be that API Gateway can’t connect to the VM or container because they aren’t running (correctly).

Retries can help, especially when integrated services are currently restarting. 

Handling API Gateway 503 Error: Service Unavailable

If you see a 503 error, most of the time, it means the service you’re integrating takes too long to answer. 

API Gateway has a maximum hard limit of 30 seconds timeouts. If your service can’t respond in under 30 seconds, API Gateway will assume it’s unavailable and stop waiting.

If the work your service does takes around 30 seconds, you should handle things asynchronously. Respond with a 202 accepted and give the client a way to fetch the results later.

If your service usually responds well below 30 seconds but only occasionally goes over the limit, you can solve the problem with retries.

Handling API Gateway 504 Error: Endpoint Request Timed-out 

The 504 status code is a bit like 503. The difference is that 504 indicates a DNS or network problem, and 503 indicates a performance problem.

Again, this can be temporary, and a retry might solve it. After all, the internet isn’t 100% stable. 

But you usually see that issue when an integrated service isn’t running, or you got the IP or hostname wrong, either because you entered the wrong or they changed somehow after you entered them.

Conclusion

We went over all the API Gateway errors you will probably encounter, and like with anything debugging-related, things can get quite messy — especially if you have countless rows of logs to sift through.

api gateway metrics dashboard

The good news is that Dashbird integrates well with API Gateway monitoring and delivers actionable insights straight to your Slack or SMS when things go awry. 

Dashbird also works with AWS as their Advanced Technology Partner and uses the AWS Well-Architected Framework to ensure you’re on track to performance and cost optimization. If you want to try Dashbird out, it’s free for the first 1 million invocations per month.

Read our blog

Introducing easy custom event monitoring for serverless applications.

Today we are excited to announce scheduled searches – a new feature on Dashbird that allows you to track any log event across your stack, turn it into time-series metric and also configure alert notifications based on it.

Why and How to Monitor Amazon OpenSearch Service

One of the most vital aspects to monitor is the metrics. You should know how your cluster performs and if it can keep up with the traffic. Learn more about monitoring Amazon OpenSearch Service.

Why and How to Monitor AWS Elastic Load Balancing

Dashbird recently added support for ELB, so now you can keep track of your load balancers in one central place. It comes with all the information you expect from AWS monitoring services and more!

More articles

This document identifies some of the error codes and messages that Google APIs return. Specifically, the errors listed here are in the global, or default, domain for Google APIs. Many APIs also define their own domains, which identify API-specific errors that are not in the global domain. For those errors, the value of the domain property in the JSON response will be an API-specific value, such as youtube.parameter.

This page lists errors by their HTTP status codes as defined in RFC 7231.

The sample JSON response below demonstrates how a global error is communicated:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "invalidParameter",
    "message": "Invalid string value: 'asdf'. Allowed values: [mostpopular]",
    "locationType": "parameter",
    "location": "chart"
   }
  ],
  "code": 400,
  "message": "Invalid string value: 'asdf'. Allowed values: [mostpopular]"
 }
}

Errors

  1. MOVED_PERMANENTLY (301)
  2. SEE_OTHER (303)
  3. NOT_MODIFIED (304)
  4. TEMPORARY_REDIRECT (307)
  5. BAD_REQUEST (400)
  6. UNAUTHORIZED (401)
  7. PAYMENT_REQUIRED (402)
  8. FORBIDDEN (403)
  9. NOT_FOUND (404)
  10. METHOD_NOT_ALLOWED (405)
  11. CONFLICT (409)
  12. GONE (410)
  13. PRECONDITION_FAILED (412)
  14. REQUEST_ENTITY_TOO_LARGE (413)
  15. REQUESTED_RANGE_NOT_SATISFIABLE (416)
  16. EXPECTATION_FAILED (417)
  17. PRECONDITION_REQUIRED (428)
  18. TOO_MANY_REQUESTS (429)
  19. INTERNAL_SERVER_ERROR (500)
  20. NOT_IMPLEMENTED (501)
  21. SERVICE_UNAVAILABLE (503)

MOVED_PERMANENTLY (301)

Error code Description
movedPermanently This request and future requests for the same operation have to be sent to the URL specified in the Location header of this response instead of to the URL to which this request was sent.

SEE_OTHER (303)

Error code Description
seeOther Your request was processed successfully. To obtain your response, send a GET request to the URL specified in the Location header.
mediaDownloadRedirect Your request was processed successfully. To obtain your response, send a GET request to the URL specified in the Location header.

NOT_MODIFIED (304)

Error code Description
notModified The condition set for an If-None-Match header was not met. This response indicates that the requested document has not been modified and that a cached response should be retrieved. Check the value of the If-None-Match HTTP request header.

TEMPORARY_REDIRECT (307)

Error code Description
temporaryRedirect To have your request processed, resend it to the URL specified in the Location header of this response.

BAD_REQUEST (400)

Error code Description
badRequest The API request is invalid or improperly formed. Consequently, the API server could not understand the request.
badBinaryDomainRequest The binary domain request is invalid.
badContent The content type of the request data or the content type of a part of a multipart request is not supported.
badLockedDomainRequest The locked domain request is invalid.
corsRequestWithXOrigin The CORS request contains an XD3 X-Origin header, which is indicative of a bad CORS request.
endpointConstraintMismatch The request failed because it did not match the specified API. Check the value of the URL path to make sure it is correct.
invalid The request failed because it contained an invalid value. The value could be a parameter value, a header value, or a property value.
invalidAltValue The alt parameter value specifies an unknown output format.
invalidHeader The request failed because it contained an invalid header.
invalidParameter The request failed because it contained an invalid parameter or parameter value. Review the API documentation to determine which parameters are valid for your request.
invalidQuery The request is invalid. Check the API documentation to determine what parameters are supported for the request and to see if the request contains an invalid combination of parameters or an invalid parameter value. Check the value of the q request parameter.
keyExpired The API key provided in the request expired, which means the API server is unable to check the quota limit for the application making the request. Check the Google Developers Console for more information or to obtain a new key.
keyInvalid The API key provided in the request is invalid, which means the API server is unable to check the quota limit for the application making the request. Use the Google Developers Console to find your API key or to obtain one.
lockedDomainCreationFailure The OAuth token was received in the query string, which this API forbids for response formats other than JSON or XML. If possible, try sending the OAuth token in the Authorization header instead.
notDownload Only media downloads requests can be sent to /download/* URL paths. Resend the request to the same path, but without the /download prefix.
notUpload The request failed because it is not an upload request, and only upload requests can be sent to /upload/* URIs. Try resending the request to the same path, but without the /upload prefix.
parseError The API server cannot parse the request body.
required The API request is missing required information. The required information could be a parameter or resource property.
tooManyParts The multipart request failed because it contains too many parts
unknownApi The API that the request is calling is not recognized.
unsupportedMediaProtocol The client is using an unsupported media protocol.
unsupportedOutputFormat The alt parameter value specifies an output format that is not supported for this service. Check the value of the alt request parameter.
wrongUrlForUpload The request is an upload request, but it failed because it was not sent to the proper URI. Upload requests must be sent to URIs that contain the /upload/* prefix. Try resending the request to the same path, but with the /upload prefix.
Error code Description
unauthorized The user is not authorized to make the request.
authError The authorization credentials provided for the request are invalid. Check the value of the Authorization HTTP request header.
expired Session Expired. Check the value of the Authorization HTTP request header.
lockedDomainExpired The request failed because a previously valid locked domain has expired.
required The user must be logged in to make this API request. Check the value of the Authorization HTTP request header.

PAYMENT_REQUIRED (402)

Error code Description
dailyLimitExceeded402 A daily budget limit set by the developer has been reached.
quotaExceeded402 The requested operation requires more resources than the quota allows. Payment is required to complete the operation.
user402 The requested operation requires some kind of payment from the authenticated user.

FORBIDDEN (403)

Error code Description
forbidden The requested operation is forbidden and cannot be completed.
accessNotConfigured Your project is not configured to access this API. Please use the Google Developers Console to activate the API for your project.
accessNotConfigured The project has been blocked due to abuse. See http://support.google.com/code/go/developer_compliance.
accessNotConfigured The project has been marked for deletion.
accountDeleted The user account associated with the request’s authorization credentials has been deleted. Check the value of the Authorization HTTP request header.
accountDisabled The user account associated with the request’s authorization credentials has been disabled. Check the value of the Authorization HTTP request header.
accountUnverified The email address for the user making the request has not been verified. Check the value of the Authorization HTTP request header.
concurrentLimitExceeded The request failed because a concurrent usage limit has been reached.
dailyLimitExceeded A daily quota limit for the API has been reached.
dailyLimitExceeded The daily quota limit has been reached, and the project has been blocked due to abuse. See the Google APIs compliance support form to help resolve the issue.
dailyLimitExceededUnreg The request failed because a daily limit for unauthenticated API use has been hit. Continued use of the API requires signup through the Google Developers Console.
downloadServiceForbidden The API does not support a download service.
insufficientAudience The request cannot be completed for this audience.
insufficientAuthorizedParty The request cannot be completed for this application.
insufficientPermissions The authenticated user does not have sufficient permissions to execute this request.
limitExceeded The request cannot be completed due to access or rate limitations.
lockedDomainForbidden This API does not support locked domains.
quotaExceeded The requested operation requires more resources than the quota allows.
rateLimitExceeded Too many requests have been sent within a given time span.
rateLimitExceededUnreg A rate limit has been exceeded and you must register your application to be able to continue calling the API. Please sign up using the Google Developers Console.
responseTooLarge The requested resource is too large to return.
servingLimitExceeded The overall rate limit specified for the API has already been reached.
sslRequired SSL is required to perform this operation.
unknownAuth The API server does not recognize the authorization scheme used for the request. Check the value of the Authorization HTTP request header.
userRateLimitExceeded The request failed because a per-user rate limit has been reached.
userRateLimitExceededUnreg The request failed because a per-user rate limit has been reached, and the client developer was not identified in the request. Please use the Google Developer Console (https://console.developers.google.com) to create a project for your application.
variableTermExpiredDailyExceeded The request failed because a variable term quota expired and a daily limit was reached.
variableTermLimitExceeded The request failed because a variable term quota limit was reached.

NOT_FOUND (404)

Error code Description
notFound The requested operation failed because a resource associated with the request could not be found.
notFound A resource associated with the request could not be found. If you have not used this API in the last two weeks, please re-deploy the App Engine app and try calling it again.
unsupportedProtocol The protocol used in the request is not supported.

METHOD_NOT_ALLOWED (405)

Error code Description
httpMethodNotAllowed The HTTP method associated with the request is not supported.

CONFLICT (409)

Error code Description
conflict The API request cannot be completed because the requested operation would conflict with an existing item. For example, a request that tries to create a duplicate item would create a conflict, though duplicate items are typically identified with more specific errors.
duplicate The requested operation failed because it tried to create a resource that already exists.

GONE (410)

Error code Description
deleted The request failed because the resource associated with the request has been deleted

PRECONDITION_FAILED (412)

Error code Description
conditionNotMet The condition set in the request’s If-Match or If-None-Match HTTP request header was not met. See the ETag section of the HTTP specification for details. Check the value of the If-Match HTTP request header.

REQUEST_ENTITY_TOO_LARGE (413)

Error code Description
backendRequestTooLarge The request is too large.
batchSizeTooLarge The batch request contains too many elements.
uploadTooLarge The request failed because the data sent in the request is too large.

REQUESTED_RANGE_NOT_SATISFIABLE (416)

Error code Description
requestedRangeNotSatisfiable The request specified a range that cannot be satisfied.

EXPECTATION_FAILED (417)

Error code Description
expectationFailed A client expectation cannot be met by the server.

PRECONDITION_REQUIRED (428)

Error code Description
preconditionRequired The request requires a precondition that is not provided. For this request to succeed, you need to provide either an If-Match or If-None-Match header with the request.

TOO_MANY_REQUESTS (429)

Error code Description
rateLimitExceeded Too many requests have been sent within a given time span.

INTERNAL_SERVER_ERROR (500)

Error code Description
internalError The request failed due to an internal error.

NOT_IMPLEMENTED (501)

Error code Description
notImplemented The requested operation has not been implemented.
unsupportedMethod The request failed because it is trying to execute an unknown method or operation.

SERVICE_UNAVAILABLE (503)

Error code Description
backendError A backend error occurred.
backendNotConnected The request failed due to a connection error.
notReady The API server is not ready to accept requests.
  • Do care about your clients
  • Forget your platform: It’s an Integration Style
  • Use HTTP status codes until you bleed!
  • Not enough information?
  • Be more expressive!
  • How about validation errors?
  • “Talk is cheap, show me the code”

Do care about your clients


We all do”. The well known first reaction of all software developers when they first come to this sentence. But,
of course, not when we’re going to handle errors.
We, as software developers, like to only consider happy paths in our scenarios and consequently, tend to forget the fact
that Error Happens, even more than those ordinary happy cases. Honestly, I can’t even remember when was the last time I got an ok
response from a payment API, those are fail by default.
How did you handle errors while designing and implementing your very last REST API? How did you handle validation errors? How did you deal with uncaught exceptions in your services? If you didn’t answer these questions before, now it’s time to consider answering them before designing a new REST API.
Of course, The most well known and unfortunate approach is let the damn exception propagates until our beloved client sees the
beautiful stacktrace on her client! If she can’t handle our NullPointerException, she shouldn’t call herself a developer.

Forget your platform: It’s an Integration Style


In their amazing book, Enterprise Integration Patterns, Gregor Hohpe and Bobby Woolf described one of the most important aspects of applications as the following:

Interesting applications rarely live in isolation. Whether your sales application must interface
with your inventory application, your procurement application must connect to an auction site,
or your PDA’s PIM must synchronize with the corporate calendar server, it seems like any
application can be made better by integrating it with other applications.

Then they introduced four Integration Styles. Regardless of the fact that the book was mainly about Messaging Patterns, we’re going to focus on Remote Procedure Invocation. Remote Procedure Invocation is an umbrella term for all approaches that expose some of application
functionalities through a Remote Interface, like REST and RPC.
Now that we’ve established that REST is an Integration Style:

Do Not expose your platform specific conventions into the REST API

The whole point of using an Integration Style, like REST, is to let different applications developed in different platforms work together,
hopefully in a more seamless and less painful fashion. The last thing a python client developer wanna see is a bunch of Pascal Case URLs, just because the API was developed with C#. Don’t shove all those Beans into your message bodies just because you’re using Java.
For a moment, forget about the platform and strive to provide an API aligned with mainstream approaches in REST API design, like the
conventions provided by Zalando team.

Use HTTP status codes until you bleed!


Let’s start with a simple rule:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 31 Aug 2016 20:51:25 GMT

{"status": "failed"}

Never ever convey error information in 2xx and 3xx response bodies!

Many so-called RESTful services out there are using HTTP status codes incorrectly. One fundamentally wrong approach is to convey
error information through a 200 OK response. The other common and irresponsible approach is to return the stacktrace as part of 500 Internal Server Error body:

HTTP/1.1 500 Internal Server Error
Content-Type: text/plain
Content-Length: 209
Date: Sun, 18 Sep 2016 09:03:48 GMT

JAXBException occurred : unexpected element (uri:"", local:"LoginRequests").
Expected elements are <{}LoginRequest>. unexpected element
(uri:"", local:"LoginRequests"). Expected elements are <{}LoginRequest>.

Here is another simple rule to follow unconditionally:

Say goodbye to your stacktrace!

There is a handful of error status codes available on 4xx and 5xx ranges that you can use to signal client or server errors. For example, suppose we have a Geeks API and we can create a new geek using POST on /geeks endpoint. If client didn’t send the required parameters,
we can tell her about the error using a 400 Bad Request response. If authentication is required but client did not send any authentication parameters in her request, we can respond with a 401 Unauthorized response.
Other typical error responses may use 403 Forbidden, 404 Not Found, 429 Too Many Requests, 500 Internal Server Error and 503 Service Unavailable. Of course these are not all available status codes to use, for an exhaustive list of them, consider reading this Wikipedia entry.

Not enough information?


Even when we’re using HTTP status codes to indicate client or server errors, there may be some cases that we need to provide more information about the error. Sometimes we use the same status code to respond for multiple error cases. For example, the POST /geeks endpoint may return 400 Bad Request for both validation errors and when that geek already exists. In such scenarios, How client would be able to tell those errors apart?
One common solution for this problem is to use Application Level Error Codes. These are codes you define to indicate one and only one error case. For example, you may reserve error code 42 to say the geek already exists:

{
  "status_code": 400,
  "reason_phrase": "Bad Request",
  "error_code": 42
}

status_code and reason_phrase fields would come handy when someone is testing the API via browser. Anyway, clients can find out what exactly went wrong just by inspecting the error_code field.
Using a numeric error code is the most common approach to implement application level error codes. However, selecting the error code is a one of the main challenges of this approach. If we assign our error codes with no strategy and upfront thinking whatsoever, we may end up with a error code mess. One solution to this challenge is to define Ranges of error codes. For example, if our fictional REST service has two resources, we can define three ranges like the following:

  • 1 to 50 for general error codes, e.g. 1 for invalid JSON payload
  • 51 to 100 for Geeks API (under /geeks), e.g. 51 for geek already exist
  • 101 to 150 for Technologies API (under /technologies)

Since different resources aren’t equally error prone, we may assign different range sizes to different resources. Estimating each range size is the other challenge we should thought through while designing the API.
The other approach which I tend to prefer to the numeric error codes is Resource Based Error Codes. That is, we use a string prefix for each error code and that prefix is determined by the resource itself. For example:

  • All general errors are prefixed with gen-, e.g. gen-1 for invalid JSON payload
  • Geeks API errors are prefixed with geeks-, e.g. geeks-1 for geek already exists
  • Technologies API errors are prefixed with techs-, e.g. techs-1 for whatever

This way our error codes are a little more verbose but wouldn’t have those mentioned challenges:

{
  "status_code": 400,
  "reason_phrase": "Bad Request",
  "error_code": "geeks-1"
}

Be more expressive!


What is your first reaction when you see the following error response?

{
  "status_code": 400,
  "reason_phrase": "Bad Request",
  "error_code": "geeks-1"
}

I bet you would search the API documentation (if any!) like a clueless chicken to find out what the heck this geeks-1 code means? Clients would have a nicer API experience if we provide an error message corresponding to the error code:

{
  "status_code": 400,
  "reason_phrase": "Bad Request",
  "error_code": "geeks-1",
  "error_message": "The geek already exists"
}

If you live in a multilingual context, you could go one step further by changing the error_message language through Content Negotiation process. For example, if the client set the Accept-Language header to fr-FR, the error could be (Google Translate says so):

{
  "status_code": 400,
  "reason_phrase": "Bad Request",
  "error_code": "geeks-1",
  "error_message": "Le connaisseur existe déjà"
}

How about validation errors?


There is this possibility that client has more than one validation error in her request. With our current error response schema, we can only report one error with each http response. That is, in multiple validation errors scenario, first we complain about the first validation error, then the second error and so on. If we could report all validation errors at once, in addition to have a more pleasant API, we could save some extra round trips.
Anyway, we can refactor our error response model to return an array of errors (surprise!) instead of just one error:

{
  "status_code": 400,
  "reason_phrase": "Bad Request",
  "errors": [
      {"code": "geeks-2", "message": "The first_name is mandatory"},
      {"code": "geeks-3", "message": "The last_name is mandatory"}
  ]
}

“Talk is cheap, show me the code”


Here I’m gonna provide a very minimal implementation of what we’ve talked about so far with Spring Boot. All the following codes are available at github, you can skip rest of the article and check them out now. Anyway, Let’s start with error codes, The ErrorCode interface will act as a super-type for all our error codes:

/**
 * Represents API error code. Each API should implement this interface to
 * provide an error code for each error case.
 *
 * @implNote Enum implementations are good fit for this scenario.
 *
 * @author Ali Dehghani
 */
public interface ErrorCode {
    String ERROR_CODE_FOR_UNKNOWN_ERROR = "unknown";

    /**
     * Represents the error code.
     *
     * @return The resource based error code
     */
    String code();

    /**
     * The corresponding HTTP status for the given error code
     *
     * @return Corresponding HTTP status code, e.g. 400 Bad Request for a validation
     * error code
     */
    HttpStatus httpStatus();

    /**
     * Default implementation representing the Unknown Error Code. When the
     * {@linkplain ErrorCodes} couldn't find any appropriate
     * {@linkplain ErrorCode} for any given {@linkplain Exception}, it will
     * use this implementation by default.
     */
    enum UnknownErrorCode implements ErrorCode {
        INSTANCE;

        @Override
        public String code() {
            return ERROR_CODE_FOR_UNKNOWN_ERROR;
        }

        @Override
        public HttpStatus httpStatus() {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
    }
}

Each error code has a String based code and a HttpStatus corresponding to that code. There is a default implementation of this interface embedded into the interface itself called UnknownErrorCode. This implementation will be used when we couldn’t figure out what exactly went wrong in the server, which obviously is a server error.
As I said each resource should provide an implementation of this interface to define all its possible error codes. For example, Geeks API did that like the following:

enum GeeksApiErrorCodes implements ErrorCode {
    GEEK_ALREADY_EXISTS("geeks-1", HttpStatus.BAD_REQUEST);

    private final String code;
    private final HttpStatus httpStatus;

    GeeksApiErrorCodes(String code, HttpStatus httpStatus) {
        this.code = code;
        this.httpStatus = httpStatus;
    }

    @Override
    public String code() {
        return code;
    }

    @Override
    public HttpStatus httpStatus() {
        return httpStatus;
    }
}

Then we should somehow convert different exceptions to appropriate ErrorCodes. ExceptionToErrorCode strategy interface does that for us:

/**
 * Strategy interface responsible for converting an instance of
 * {@linkplain Exception} to appropriate instance of {@linkplain ErrorCode}.
 * Implementations of this interface should be accessed indirectly through
 * the {@linkplain ErrorCodes}'s factory method.
 *
 * @implSpec The {@linkplain #toErrorCode(Exception)} method should be called iff the
 * call to the {@linkplain #canHandle(Exception)} returns true for the same exception.
 *
 * @see ErrorCode
 * @see ErrorCodes
 *
 * @author Ali Dehghani
 */
public interface ExceptionToErrorCode {
    /**
     * Determines whether this implementation can handle the given exception or not.
     * Calling the {@linkplain #toErrorCode(Exception)} when this method returns
     * false, is strongly discouraged.
     *
     * @param exception The exception to examine
     * @return true if the implementation can handle the exception, false otherwise.
     */
    boolean canHandle(Exception exception);

    /**
     * Performs the actual mechanics of converting the given {@code exception}
     * to an instance of {@linkplain ErrorCode}.
     *
     * @implSpec Call this method iff the {@linkplain #canHandle(Exception)} returns
     * true.
     *
     * @param exception The exception to convert
     * @return An instance of {@linkplain ErrorCode} corresponding to the given
     * {@code exception}
     */
    ErrorCode toErrorCode(Exception exception);
}

Again each resource should provide an implementation for this interface per each defined error codes. Geeks API does that like the following:

class GeeksApiExceptionMappers {
    @Component
    static class GeeksAlreadyExceptionToErrorCode implements ExceptionToErrorCode {
        @Override
        public boolean canHandle(Exception exception) {
            return exception instanceof GeekAlreadyExists;
        }

        @Override
        public ErrorCode toErrorCode(Exception exception) {
            return GeeksApiErrorCodes.GEEK_ALREADY_EXISTS;
        }
    }
}

This basically catch all GeekAlreadyExists exceptions and convert them to GeeksApiErrorCodes.GEEK_ALREADY_EXISTS error code.
Since there would be quite a large number of implementations like this, It’s better to delegate finding the right implementation for each exception to another abstraction. ErrorCodes factory would do that like the following:

/**
 * Acts as a factory for {@linkplain ExceptionToErrorCode} implementations.
 * By calling the {@linkplain #of(Exception)} factory method, clients can
 * find the corresponding {@linkplain ErrorCode} for the given
 * {@linkplain Exception}. Behind the scenes, this factory method, first finds
 * all available implementations of the {@linkplain ExceptionToErrorCode}
 * strategy interface. Then selects the first implementation that can actually
 * handles the given exception and delegate the exception translation process
 * to that implementation.
 *
 * @implNote If the factory method couldn't find any implementation for the given
 * {@linkplain Exception}, It would return the
 * {@linkplain me.alidg.rest.errors.ErrorCode.UnknownErrorCode} which represent
 * an Unknown Error.
 *
 * @author Ali Dehghani
 */
@Component
class ErrorCodes {
    private final ApplicationContext context;

    ErrorCodes(ApplicationContext context) {
        this.context = context;
    }

    /**
     * Factory method to find the right {@linkplain ExceptionToErrorCode}
     * implementation and delegates the conversion task to that implementation.
     * If it couldn't find any registered implementation, It would return an
     * Unknown Error represented by the {@linkplain UnknownError} implementation.
     *
     * @implNote Currently this method queries Spring's
     * {@linkplain ApplicationContext} to find the {@linkplain ExceptionToErrorCode}
     * implementations. So in order to register your {@linkplain ExceptionToErrorCode}
     * implementation, you should annotate your implementation with one of
     * Spring Stereotype annotations, e.g. {@linkplain Component}.
     * Our recommendation is to use the {@linkplain Component} annotation or
     * another meta annotation based on this annotation.
     *
     * @param exception The exception to find the implementation based on that
     * @return An instance of {@linkplain ErrorCode} corresponding the given
     * {@code exception}
     */
    ErrorCode of(Exception exception) {
        return implementations()
                .filter(impl -> impl.canHandle(exception))
                .findFirst()
                .map(impl -> impl.toErrorCode(exception))
                .orElse(ErrorCode.UnknownErrorCode.INSTANCE);
    }

    /**
     * Query the {@linkplain #context} to find all available implementations of
     * {@linkplain ExceptionToErrorCode}.
     */
    private Stream<ExceptionToErrorCode> implementations() {
        return context.getBeansOfType(ExceptionToErrorCode.class).values().stream();
    }
}

Here comes the ErrorResponse class to used to as the JSON representation of each error:

/**
 * An immutable data structure representing HTTP error response bodies. JSON
 * representation of this class would be something like the following:
 * <pre>
 *     {
 *         "status_code": 404,
 *         "reason_phrase": "Not Found",
 *         "errors": [
 *             {"code": "res-15", "message": "some error message"},
 *             {"code": "res-16", "message": "yet another message"}
 *         ]
 *     }
 * </pre>
 *
 * @author Ali Dehghani
 */
@JsonAutoDetect(fieldVisibility = ANY)
class ErrorResponse {
    /**
     * The 4xx or 5xx status code for error cases, e.g. 404
     */
    private final int statusCode;

    /**
     * The HTTP reason phrase corresponding the {@linkplain #statusCode},
     * e.g. Not Found
     *
     * @see <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html">
     * Status Code and Reason Phrase</a>
     */
    private final String reasonPhrase;

    /**
     * List of application-level error code and message combinations.
     * Using these errors we provide more information about the
     * actual error
     */
    private final List<ApiError> errors;

    private ErrorResponse(int statusCode, String reason, List<ApiError> errors) {
        // Some precondition checks

        this.statusCode = statusCode;
        this.reasonPhrase = reason;
        this.errors = errors;
    }

    /**
     * Static factory method to create a {@linkplain ErrorResponse} with multiple
     * {@linkplain ApiError}s. The canonical use case of this factory method is when
     * we're handling validation exceptions, since we may have multiple validation
     * errors.
     */
    static ErrorResponse ofErrors(HttpStatus status, List<ApiError> errors) {
        return new ErrorResponse(status.value(), status.getReasonPhrase(), errors);
    }

    /**
     * Static factory method to create a {@linkplain ErrorResponse} with a single
     * {@linkplain ApiError}. The canonical use case for this method is when we trying
     * to create {@linkplain ErrorResponse}es for regular non-validation exceptions.
     */
    static ErrorResponse of(HttpStatus status, ApiError error) {
        return ofErrors(status, Collections.singletonList(error));
    }

    /**
     * An immutable data structure representing each application-level error. JSON
     * representation of this class would be something like the following:
     * <pre>
     *     {"code": "res-12", "message": "some error"}
     * </pre>
     *
     * @author Ali Dehghani
     */
    @JsonAutoDetect(fieldVisibility = ANY)
    static class ApiError {
        /**
         * The error code
         */
        private final String code;

        /**
         * Possibly localized error message
         */
        private final String message;

        ApiError(String code, String message) {
            this.code = code;
            this.message = message;
        }
    }
}

And finally to glue all of these together, a Spring MVC ExceptionHandler would catch all exceptions and render appropriate ErrorResponsees:

/**
 * Exception handler that catches all exceptions thrown by the REST layer
 * and convert them to the appropriate {@linkplain ErrorResponse}s with a
 * suitable HTTP status code.
 *
 * @see ErrorCode
 * @see ErrorCodes
 * @see ErrorResponse
 *
 * @author Ali Dehghani
 */
@ControllerAdvice
class ApiExceptionHandler {
    private static final String NO_MESSAGE_AVAILABLE = "No message available";

    /**
     * Factory to convert the given {@linkplain Exception} to an instance of
     * {@linkplain ErrorCode}
     */
    private final ErrorCodes errorCodes;

    /**
     * Responsible for finding the appropriate error message(s) based on the given
     * {@linkplain ErrorCode} and {@linkplain Locale}
     */
    private final MessageSource apiErrorMessageSource;

    /**
     * Construct a valid instance of the exception handler
     *
     * @throws NullPointerException If either of required parameters were {@code null}
     */
    ApiExceptionHandler(ErrorCodes errorCodes, MessageSource apiErrorMessageSource) {
        Objects.requireNonNull(errorCodes);
        Objects.requireNonNull(apiErrorMessageSource);

        this.errorCodes = errorCodes;
        this.apiErrorMessageSource = apiErrorMessageSource;
    }

    /**
     * Catches all non-validation exceptions and tries to convert them to
     * appropriate HTTP Error responses
     *
     * <p>First using the {@linkplain #errorCodes} will find the corresponding
     * {@linkplain ErrorCode} for the given {@code exception}. Then based on
     * the resolved {@linkplain Locale}, a suitable instance of
     * {@linkplain ErrorResponse} with appropriate and localized message will
     * return to the client. {@linkplain ErrorCode} itself determines the HTTP
     * status of the response.
     *
     * @param exception The exception to convert
     * @param locale The locale that usually resolved by {@code Accept-Language}
     * header. This locale will determine the language of the returned error
     * message.
     * @return An appropriate HTTP Error Response with suitable status code
     * and error messages
     */
    @ExceptionHandler(ServiceException.class)
    ResponseEntity<ErrorResponse> handleExceptions(ServiceException exception,
                                                   Locale locale) {
        ErrorCode errorCode = errorCodes.of(exception);
        ErrorResponse errorResponse = ErrorResponse.of(errorCode.httpStatus(),
                                                       toApiError(errorCode, locale));

        return ResponseEntity.status(errorCode.httpStatus()).body(errorResponse);
    }

    /**
     * Convert the passed {@code errorCode} to an instance of
     * {@linkplain ErrorResponse} using the given {@code locale}
     */
    private ErrorResponse.ApiError toApiError(ErrorCode errorCode, Locale locale) {
        String message;
        try {
            message = apiErrorMessageSource.getMessage(errorCode.code(),
                                                       new Object[]{},
                                                       locale);
        } catch (NoSuchMessageException e) {
            message = NO_MESSAGE_AVAILABLE;
        }

        return new ErrorResponse.ApiError(errorCode.code(), message);
    }
}

REST API использует строку состояния в HTTP ответе (статус ответа), чтобы информировать Клиентов о результате запроса.

Вообще HTTP определяет 40 стандартных кодов состояния (статусов ответа), которые делятся на пять категорий. Ниже выделены только те коды состояния, которые часто используются в REST API.

Категория Описание
1xx: Информация В этот класс содержит заголовки информирующие о процессе передачи. Это обычно предварительный ответ, состоящий только из Status-Line и опциональных заголовков, и завершается пустой строкой. Нет обязательных заголовков. Серверы НЕ ДОЛЖНЫ посылать 1xx ответы HTTP/1.0 клиентам.
2xx: Успех Этот класс кодов состояния указывает, что запрос клиента был успешно получен, понят, и принят.
3xx: Перенаправление Коды этого класса сообщают клиенту, что для успешного выполнения операции необходимо сделать другой запрос, как правило, по другому URI. Из данного класса пять кодов 301, 302, 303, 305 и 307 относятся непосредственно к перенаправлениям.
4xx: Ошибка клиента Класс кодов 4xx предназначен для указания ошибок со стороны клиента.
5xx: Ошибка сервера Коды ответов, начинающиеся с «5» указывают на случаи, когда сервер знает, что произошла ошибка или он не может обработать запрос.

Коды состояний в REST

Звездочкой * помечены популярные (часто используемые) коды ответов.

200 * (OK)

Запрос выполнен успешно. Информация, возвращаемая с ответом зависит от метода, используемого в запросе, например при:

  • GET Получен объект, соответствующий запрошенному ресурсу.
  • HEAD Получены поля заголовков, соответствующие запрошенному ресурсу, тело ответа пустое.
  • POST Запрошенное действие выполнено.

201 * (Created — Создано)

REST API отвечает кодом состояния 201 при каждом создании ресурса в коллекции. Также могут быть случаи, когда новый ресурс создается в результате какого-либо действия контроллера, и в этом случае 201 также будет подходящем ответом.

Ссылка (URL) на новый ресурс может быть в теле ответа или в поле заголовка ответа Location.

Сервер должен создать ресурс перед тем как вернуть 201 статус. Если это невозможно сделать сразу, тогда сервер должен ответить кодом 202 (Accepted).

202 (Accepted — Принято)

Ответ 202 обычно используется для действий, которые занимают много времени для обработки и не могут быть выполнены сразу. Это означает, что запрос принят к обработке, но обработка не завершена.

Его цель состоит в том, чтобы позволить серверу принять запрос на какой-либо другой процесс (возможно, пакетный процесс, который выполняется только один раз в день), не требуя, чтобы соединение агента пользователя с сервером сохранялось до тех пор, пока процесс не будет завершен.

Сущность, возвращаемая с этим ответом, должна содержать указание на текущее состояние запроса и указатель на монитор состояния (расположение очереди заданий) или некоторую оценку того, когда пользователь может ожидать выполнения запроса.

203 (Non-Authoritative Information — Неавторитетная информация)

Предоставленная информация взята не из оригинального источника (а, например, из кэша, который мог устареть, или из резервной копии, которая могла потерять актуальность). Этот факт отражен в заголовке ответа и подтверждается этим кодом. Предоставленная информация может совпадать, а может и не совпадать с оригинальными данными.

204 * (No Content — Нет контента)

Код состояния 204 обычно отправляется в ответ на запрос PUT, POST или DELETE, когда REST API отказывается отправлять обратно любое сообщение о состоянии проделанной работы.

API может также отправить 204 статус в ответ на GET запрос, чтобы указать, что запрошенный ресурс существует, но не имеет данных для добавления их в тело ответа.

Ответ 204 не должен содержать тело сообщения и, таким образом, всегда завершается первой пустой строкой после полей заголовка.

205 — (Reset Content — Сброшенное содержимое)

Сервер успешно обработал запрос и обязывает клиента сбросить введенные пользователем данные. В ответе не должно передаваться никаких данных (в теле ответа). Обычно применяется для возврата в начальное состояние формы ввода данных на клиенте.

206 — (Partial Content — Частичное содержимое)

Сервер выполнил часть GET запроса ресурса. Запрос ДОЛЖЕН был содержать поле заголовка Range (секция 14.35), который указывает на желаемый диапазон и МОГ содержать поле заголовка If-Range (секция 14.27), который делает запрос условным.

Запрос ДОЛЖЕН содержать следующие поля заголовка:

  • Либо поле Content-Range (секция 14.16), который показывает диапазон, включённый в этот запрос, либо Content-Type со значением multipart/byteranges, включающими в себя поля Content-Range для каждой части. Если в заголовке запроса есть поле Content-Length, его значение ДОЛЖНО совпадать с фактическим количеством октетов, переданных в теле сообщения.
  • Date
  • ETag и/или Content-Location, если ранее был получен ответ 200 на такой же запрос.
  • Expires, Cache-Control, и/или Vary, если значение поля изменилось с момента отправления последнего такого же запроса

Если ответ 206 — это результат выполнения условного запроса, который использовал строгий кэш-валидатор (подробнее в секции 13.3.3), в ответ НЕ СЛЕДУЕТ включать какие-либо другие заголовки сущности. Если такой ответ — результат выполнения запроса If-Range, который использовал «слабый» валидатор, то ответ НЕ ДОЛЖЕН содержать другие заголовки сущности; это предотвращает несоответствие между закэшированными телами сущностей и обновлёнными заголовками. В противном случае ответ ДОЛЖЕН содержать все заголовки сущностей, которые вернули статус 200 (OK) на тот же запрос.

Кэш НЕ ДОЛЖЕН объединять ответ 206 с другими ранее закэшированными данными, если поле ETag или Last-Modified в точности не совпадают (подробнее в секции 16.5.4)

Кэш, который не поддерживает заголовки Range и Content-Range НЕ ДОЛЖЕН кэшировать ответы 206 (Partial).

300 — (Multiple Choices — Несколько вариантов)

По указанному URI существует несколько вариантов предоставления ресурса по типу MIME, по языку или по другим характеристикам. Сервер передаёт с сообщением список альтернатив, давая возможность сделать выбор клиенту автоматически или пользователю.

Если это не запрос HEAD, ответ ДОЛЖЕН включать объект, содержащий список характеристик и адресов, из которого пользователь или агент пользователя может выбрать один наиболее подходящий. Формат объекта определяется по типу данных приведённых в Content-Type поля заголовка. В зависимости от формата и возможностей агента пользователя, выбор наиболее подходящего варианта может выполняться автоматически. Однако эта спецификация не определяет никакого стандарта для автоматического выбора.

Если у сервера есть предпочтительный выбор представления, он ДОЛЖЕН включить конкретный URI для этого представления в поле Location; агент пользователя МОЖЕТ использовать заголовок Location для автоматического перенаправления к предложенному ресурсу. Этот запрос может быть закэширован, если явно не было указано иного.

301 (Moved Permanently — Перемещено навсегда)

Код перенаправления. Указывает, что модель ресурсов REST API была сильно изменена и теперь имеет новый URL. Rest API должен указать новый URI в заголовке ответа Location, и все будущие запросы должны быть направлены на указанный URI.

Вы вряд ли будете использовать этот код ответа в своем API, так как вы всегда можете использовать версию API для нового API, сохраняя при этом старый.

302 (Found — Найдено)

Является распространенным способом выполнить перенаправление на другой URL. HTTP-ответ с этим кодом должен дополнительно предоставит URL-адрес куда перенаправлять в поле заголовка Location. Агенту пользователя (например, браузеру) предлагается в ответе с этим кодом сделать второй запрос на новый URL.

Многие браузеры реализовали этот код таким образом, что нарушили стандарт. Они начали изменять Тип исходного запроса, например с POST на GET. Коды состояния 303 и 307 были добавлены для серверов, которые хотят однозначно определить, какая реакция ожидается от клиента.

303 (See Other — Смотрите другое)

Ответ 303 указывает, что ресурс контроллера завершил свою работу, но вместо отправки нежелательного тела ответа он отправляет клиенту URI ресурса. Это может быть URI временного сообщения о состоянии ресурса или URI для уже существующего постоянного ресурса.

Код состояния 303 позволяет REST API указать ссылку на ресурс, не заставляя клиента загружать ответ. Вместо этого клиент может отправить GET запрос на URL указанный в заголовке Location.

Ответ 303 не должен кэшироваться, но ответ на второй (перенаправленный) запрос может быть кэшируемым.

304 * (Not Modified — Не изменен)

Этот код состояния похож на 204 (Нет контента), так как тело ответа должно быть пустым. Ключевое различие состоит в том, что 204 используется, когда нет ничего для отправки в теле, тогда как 304 используется, когда ресурс не был изменен с версии, указанной заголовками запроса If-Modified-Since или If-None-Match.

В таком случае нет необходимости повторно передавать ресурс, так как у клиента все еще есть ранее загруженная копия.

Все это экономит ресурсы клиента и сервера, так как только заголовки должны быть отправлены и приняты, и серверу нет необходимости генерировать контент снова, а клиенту его получать.

305 — (Use Proxy — Используйте прокси)

Доступ к запрошенному ресурсу ДОЛЖЕН быть осуществлен через прокси-сервер, указанный в поле Location. Поле Location предоставляет URI прокси. Ожидается, что получатель повторит этот запрос с помощью прокси. Ответ 305 может генерироваться ТОЛЬКО серверами-источниками.

Заметьте: в спецификации RFC 2068 однозначно не сказано, что ответ 305 предназначен для перенаправления единственного запроса, и что он должен генерироваться только сервером-источником. Упущение этих ограничений вызвало ряд значительных последствий для безопасности.

Многие HTTP клиенты (такие, как Mozilla и Internet Explorer) обрабатывают этот статус некорректно прежде всего из соображений безопасности.

307 (Temporary Redirect — Временный редирект)

Ответ 307 указывает, что rest API не будет обрабатывать запрос клиента. Вместо этого клиент должен повторно отправить запрос на URL, указанный в заголовке Location. Однако в будущих запросах клиент по-прежнему должен использоваться исходный URL.

Rest API может использовать этот код состояния для назначения временного URL запрашиваемому ресурсу.

Если метод запроса не HEAD, тело ответа должно содержать короткую заметку с гиперссылкой на новый URL. Если код 307 был получен в ответ на запрос, отличный от GET или HEAD, Клиент не должен автоматически перенаправлять запрос, если он не может быть подтвержден Клиентом, так как это может изменить условия, при которых был создан запрос.

308 — (Permanent Redirect — Постоянное перенаправление) (experimental)

Нужно повторить запрос на другой адрес без изменения применяемого метода.

Этот и все последующие запросы нужно повторить на другой URI. 307 и 308 (как предложено) Схож в поведении с 302 и 301, но не требуют замены HTTP метода. Таким образом, например, отправку формы на «постоянно перенаправленный» ресурс можно продолжать без проблем.

400 * (Bad Request — Плохой запрос)

Это общий статус ошибки на стороне Клиента. Используется, когда никакой другой код ошибки 4xx не уместен. Ошибки могут быть как неправильный синтаксис запроса, неверные параметры запроса, запросы вводящие в заблуждение или маршрутизатор и т.д.

Клиент не должен повторять точно такой же запрос.

401 * (Unauthorized — Неавторизован)

401 сообщение об ошибке указывает, что клиент пытается работать с закрытым ресурсом без предоставления данных авторизации. Возможно, он предоставил неправильные учетные данные или вообще ничего. Ответ должен включать поле заголовка WWW-Authenticate, содержащего описание проблемы.

Клиент может повторить запрос указав в заголовке подходящее поле авторизации. Если это уже было сделано, то в ответе 401 будет указано, что авторизация для указанных учетных данных не работает. Если в ответе 401 содержится та же проблема, что и в предыдущем ответе, и Клиент уже предпринял хотя бы одну попытку проверки подлинности, то пользователю Клиента следует представить данные полученные в ответе, владельцу сайта, так как они могут помочь в диагностике проблемы.

402 — (Payment Required — Требуется оплата)

Этот код зарезервирован для использования в будущем.

Предполагается использовать в будущем. В настоящий момент не используется. Этот код предусмотрен для платных пользовательских сервисов, а не для хостинговых компаний. Имеется в виду, что эта ошибка не будет выдана хостинговым провайдером в случае просроченной оплаты его услуг. Зарезервирован, начиная с HTTP/1.1.

403 * (Forbidden — Запрещено)

Ошибка 403 указывает, что rest API отказывается выполнять запрос клиента, т.е. Клиент не имеет необходимых разрешений для доступа. Ответ 403 не является случаем, когда нужна авторизация (для ошибки авторизации используется код 401).

Попытка аутентификация не поможет, и повторные запросы не имеют смысла.

404 * (Not Found — Не найдено)

Указывает, что rest API не может сопоставить URL клиента с ресурсом, но этот URL может быть доступен в будущем. Последующие запросы клиента допустимы.

404 не указывает, является ли состояние временным или постоянным. Для указания постоянного состояния используется код 410 (Gone — Пропал). 410 использоваться, если сервер знает, что старый ресурс постоянно недоступен и более не имеет адреса.

405 (Method Not Allowed — Метод не разрешен)

API выдает ошибку 405, когда клиент пытался использовать HTTP метод, который недопустим для ресурса. Например, указан метод PUT, но такого метода у ресурса нет.

Ответ 405 должен включать Заголовок Allow, в котором перечислены поддерживаемые HTTP методы, например, Allow: GET, POST.

406 (Not Acceptable — Неприемлемый)

API не может генерировать предпочитаемые клиентом типы данных, которые указаны в заголовке запроса Accept. Например, запрос клиента на данные в формате application/xml получит ответ 406, если API умеет отдавать данные только в формате application/json.

В таких случаях Клиент должен решить проблему данных у себя и только потом отправлять запросы повторно.

407 — (Proxy Authentication Required — Требуется прокси-аутентификация)

Ответ аналогичен коду 401, за исключением того, что аутентификация производится для прокси-сервера. Механизм аналогичен идентификации на исходном сервере.

Пользователь должен сначала авторизоваться через прокси. Прокси-сервер должен вернуть Proxy-Authenticate заголовок, содержащий запрос ресурса. Клиент может повторить запрос вместе с Proxy-Authenticate заголовком. Появился в HTTP/1.1.

408 — (Request Timeout — Таймаут запроса)

Время ожидания сервером передачи от клиента истекло. Клиент не предоставил запрос за то время, пока сервер был готов его принят. Клиент МОЖЕТ повторить запрос без изменений в любое время.

Например, такая ситуация может возникнуть при загрузке на сервер объёмного файла методом POST или PUT. В какой-то момент передачи источник данных перестал отвечать, например, из-за повреждения компакт-диска или потери связи с другим компьютером в локальной сети. Пока клиент ничего не передаёт, ожидая от него ответа, соединение с сервером держится. Через некоторое время сервер может закрыть соединение со своей стороны, чтобы дать возможность другим клиентам сделать запрос.

409 * (Conflict — Конфликт)

Запрос нельзя обработать из-за конфликта в текущем состоянии ресурса. Этот код разрешается использовать только в тех случаях, когда ожидается, что пользователь может самостоятельно разрешить этот конфликт и повторить запрос. В тело ответа СЛЕДУЕТ включить достаточное количество информации для того, чтобы пользователь смог понять причину конфликта. В идеале ответ должен содержать такую информацию, которая поможет пользователю или его агенту исправить проблему. Однако это не всегда возможно и это не обязательно.

Как правило, конфликты происходят во время PUT-запроса. Например, во время использования версионирования, если сущность, к которой обращаются методом PUT, содержит изменения, конфликтующие с теми, что были сделаны ранее третьей стороной, серверу следует использовать ответ 409, чтобы дать понять пользователю, что этот запрос нельзя завершить. В этом случае в ответной сущности должен содержаться список изменений между двумя версиями в формате, который указан в поле заголовка Content-Type.

410 — (Gone — Исчез)

Такой ответ сервер посылает, если ресурс раньше был по указанному URL, но был удалён и теперь недоступен. Серверу в этом случае неизвестно и местоположение альтернативного документа, например, копии. Если у сервера есть подозрение, что документ в ближайшее время может быть восстановлен, то лучше клиенту передать код 404. Появился в HTTP/1.1.

411 — (Length Required — Требуется длина)

Для указанного ресурса клиент должен указать Content-Length в заголовке запроса. Без указания этого поля не стоит делать повторную попытку запроса к серверу по данному URI. Такой ответ естественен для запросов типа POST и PUT. Например, если по указанному URI производится загрузка файлов, а на сервере стоит ограничение на их объём. Тогда разумней будет проверить в самом начале заголовок Content-Length и сразу отказать в загрузке, чем провоцировать бессмысленную нагрузку, разрывая соединение, когда клиент действительно пришлёт слишком объёмное сообщение.

412 — (Precondition Failed — Предварительное условие не выполнено)

Возвращается, если ни одно из условных полей заголовка запроса не было выполнено.

Когда клиент указывает rest API выполнять запрос только при выполнении определенных условий, а API не может выполнить запрос при таких условиях, то возвращается ответ 412.

Этот код ответа позволяет клиенту записывать предварительные условия в метаинформации текущего ресурса, таким образом, предотвращая применение запрошенного метода к ресурсу, кроме того, что ожидается.

413 — (Request Entity Too Large — Сущность запроса слишком большая)

Возвращается в случае, если сервер отказывается обработать запрос по причине слишком большого размера тела запроса. Сервер может закрыть соединение, чтобы прекратить дальнейшую передачу запроса.

Если проблема временная, то рекомендуется в ответ сервера включить заголовок Retry-After с указанием времени, по истечении которого можно повторить аналогичный запрос.

414 — (Request-URI Too Long — Запрос-URI Слишком длинный)

Сервер не может обработать запрос из-за слишком длинного указанного URL. Эту редкую ошибку можно спровоцировать, например, когда клиент пытается передать длинные параметры через метод GET, а не POST, когда клиент попадает в «чёрную дыру» перенаправлений (например, когда префикс URI указывает на своё же окончание), или когда сервер подвергается атаке со стороны клиента, который пытается использовать дыры в безопасности, которые встречаются на серверах с фиксированной длиной буфера для чтения или обработки Request-URI.

415 (Unsupported Media Type — Неподдерживаемый медиа тип)

Сообщение об ошибке 415 указывает, что API не может обработать предоставленный клиентом Тип медиа, как указано в заголовке запроса Content-Type.

Например, запрос клиента содержит данные в формате application/xml, а API готов обработать только application/json. В этом случае клиент получит ответ 415.

Например, клиент загружает изображение как image/svg+xml, но сервер требует, чтобы изображения использовали другой формат.

428 — (Precondition Required — Требуется предварительное условие)

Код состояния 428 указывает, что исходный сервер требует, чтобы запрос был условным.

Его типичное использование — избежать проблемы «потерянного обновления», когда клиент ПОЛУЧАЕТ состояние ресурса, изменяет его и ОТПРАВЛЯЕТ обратно на сервер, когда тем временем третья сторона изменила состояние на сервере, что привело к конфликту. Требуя, чтобы запросы были условными, сервер может гарантировать, что клиенты работают с правильными копиями.

Ответы с этим кодом состояния ДОЛЖНЫ объяснять, как повторно отправить запрос.

429 — (Too Many Requests — Слишком много запросов)

Пользователь отправил слишком много запросов за заданный промежуток времени.

Представления ответа ДОЛЖНЫ включать подробности, объясняющие условие, и МОГУТ включать заголовок Retry-After, указывающий, как долго ждать, прежде чем делать новый запрос.

431 — (Request Header Fields Too Large — Слишком большие поля заголовка запроса)

Код состояния 431 указывает на то, что сервер не желает обрабатывать запрос, поскольку его поля заголовка слишком велики. Запрос МОЖЕТ быть отправлен повторно после уменьшения размера полей заголовка запроса.

Его можно использовать как в случае, когда совокупность полей заголовка запроса слишком велика, так и в случае неисправности одного поля заголовка. В последнем случае представление ответа ДОЛЖНО указывать, какое поле заголовка было слишком большим.

444 — (No Response — Нет ответа) (Nginx)

Код ответа Nginx. Сервер не вернул информацию и закрыл соединение. (полезно в качестве сдерживающего фактора для вредоносных программ)

451 — (Unavailable For Legal Reasons — Недоступен по юридическим причинам)

Доступ к ресурсу закрыт по юридическим причинам. Наиболее близким из существующих является код 403 Forbidden (сервер понял запрос, но отказывается его обработать). Однако в случае цензуры, особенно когда это требование к провайдерам заблокировать доступ к сайту, сервер никак не мог понять запроса — он его даже не получил. Совершенно точно подходит другой код: 305 Use Proxy. Однако такое использование этого кода может не понравиться цензорам. Было предложено несколько вариантов для нового кода, включая «112 Emergency. Censorship in action» и «460 Blocked by Repressive Regime»

500 * (Internal Server Error — Внутренняя ошибка сервера)

Общий ответ при ошибке в коде. Универсальное сообщение о внутренней ошибке сервера, когда никакое более определенное сообщение не подходит.

Большинство веб-платформ автоматически отвечают этим кодом состояния, когда при выполнении кода обработчика запроса возникла ошибка.

Ошибка 500 никогда не зависит от клиента, поэтому для клиента разумно повторить точно такой же запрос, и надеяться что в этот раз сервер отработает без ошибок.

501 (Not Implemented — Не реализован)

Серверу либо неизвестен метод запроса, или ему (серверу) не хватает возможностей выполнить запрос. Обычно это подразумевает будущую доступность (например, новая функция API веб-сервиса).

Если же метод серверу известен, но он не применим к данному ресурсу, то нужно вернуть ответ 405.

502 — (Bad Gateway — Плохой шлюз)

Сервер, выступая в роли шлюза или прокси-сервера, получил некорректный ответ от вышестоящего сервера, к которому он обратился. Появился в HTTP/1.0.

503 — (Service Unavailable — Служба недоступна)

Сервер не может обработать запрос из-за временной перегрузки или технических работ. Это временное состояние, из которого сервер выйдет через какое-то время. Если это время известно, то его МОЖНО передать в заголовке Retry-After.

504 — (Gateway Timeout — Таймаут шлюза)

Сервер, в роли шлюза или прокси-сервера, не дождался в рамках установленного таймаута ответа от вышестоящего сервера текущего запроса.

505 — (HTTP Version Not Supported — Версия HTTP не поддерживается)

Сервер не поддерживает или отказывается поддерживать указанную в запросе версию протокола HTTP.

510 — (Not Extended — Не расширен)

В запросе не соблюдена политика доступа к ресурсу. Сервер должен отправить обратно всю информацию, необходимую клиенту для отправки расширенного запроса. Указание того, как расширения информируют клиента, выходит за рамки данной спецификации.

Источники и более подробная информация:

  • https://restapitutorial.ru/httpstatuscodes.html
  • https://www.restapitutorial.com/httpstatuscodes.html
  • https://restfulapi.net/http-status-codes/
  • https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/428

Понравилась статья? Поделить с друзьями:
  • Apache error page custom
  • Api error 200 entry not found occurred
  • Api error 101 server not found occurred
  • Api development tools telegram error
  • Apache error log где найти