I'm using Swagger to do the documentation of the Laravel API's, and sometimes there is also testing apart from POSTMAN, the issue is that the GET methods with parameters do not work Route::get('/searchProduct/{id}','Api\ReportController#getProductsByID');
But if the GET method does not have parameters it works perfectly. In Swagger I realized that when I make the query I don't enter the parameter in {id} but I believe after {id}?id=4
This is my route
My route
Route::get('/searchProduct/{id}','Api\ReportController#getProductsByID');
Result in Swagger
www.x.cl/api/searchProduct/{id}?id=4 //ERROR
How it should work
www.x.cl/api/searchProduct/4
Because in POSTMAN I only change my ID by the number and the search works for me.
This is my controller
/**
* #OA\Get(
* path="/api/searchProduct/{id}",
* summary="Search Product by Status",
* description="Lorem ipsun",
* security={
* {"bearer_token":{}},
* },
* #OA\Parameter(
* name="id",
* in="query",
* description="Buscar por estado",
* required=true,
* ),
* #OA\Response(
* response=200,
* description="OK",
* #OA\MediaType(
* mediaType="application/json",
* )
* ),
* #OA\Response(
* response="default",
* description="Ha ocurrido un error."
* ),
* #OA\Response(
* response="401",
* description="No se ha autenticado, ingrese el token."
* ),
* )
*/
public function getProductsByID($uuid){
$validated = Product::status($uuid);
return ReportResource::collection($validated);
}
Try replacing in="query", with in="path", here :
* #OA\Parameter(
* name="id",
* in="query",
* description="Buscar por estado",
* required=true,
* ),
Query refers to "query string", the set of ampersand-separated key/value pairs that come after ? in the URL.
Related
I am using swagger with Laravel to document the application and I want to add 2 headers for all request and I am not finding how.
I have authorization with swagger:
and I would like that after the authorization set in all following requests 2 headers:
x-session-id: session seted in swagger authorization
X-Requested-With: X-Requested-With.
One of the request that it must have the headers is the following:
/**
*
* #OA\Get(
* path="/place/list",
* tags={"Lugares"},
* summary="Get places",
* #OA\Response(
* response=200,
* description="Get places list"
* ),
* #OA\Response(
* response="default",
* description="Has been occurs a problem."
* )
* )
*/
public function list()
{
$session = session()->get('rismi2_session_data');
$selDominioId = $session['sel_dominio.id'];
$plantas = $this->placeRepository->getPlace($selDominioId);
return placeResource::make($plantas);
}
You can add SecuritySchemes to your API.
Link: https://swagger.io/docs/specification/authentication/api-keys/
It must be used in your API declaration.
Example:
/**
*
* #OA\Info(
* version="1.0",
* title="API"
* )
*
* #OA\SecurityScheme(
* securityScheme="XXX",
* in="header",
* name="YYY",
* type="ZZZ",
* )
*/
I have this a project that is using Laravel for the api and swagger for documentation
I have this method in my login controller:
/**
* Handle an incoming authentication request.
*
*
* #OA\Post(
* tags={"UnAuthorize"},
* path="/login",
* summary="User Login",
* #OA\RequestBody(
* #OA\MediaType(
* mediaType="application/json",
* #OA\Schema(
* type="object",
* ref="#/components/schemas/LoginRequest",
* )
* )
* ),
* #OA\Response(
* response="200",
* description="An example resource",
* #OA\JsonContent(
* type="object",
* #OA\Property(
* format="string",
* default="20d338931e8d6bd9466edeba78ea7dce7c7bc01aa5cc5b4735691c50a2fe3228",
* description="token",
* property="token"
* )
* ),
* #OA\JsonContent(ref="#/components/schemas/UserResource")
* ),
* #OA\Response(response="401", description="fail"),
* )
*
* #param \App\Http\Requests\Auth\LoginRequest $request
* #return \Illuminate\Http\JsonResponse
*/
public function store(LoginRequest $request)
{
$request->authenticate();
return response()->json(
[
"token" => $request->user()->createToken($request->email)->plainTextToken,
"user" => $request->user();
]
);
}
then, when I run this command: php artisan l5-swagger:generate ,it displays this error:
c:\myproject\vendor\zircote\swagger-php\src\Logger.php:40
36▕ $this->log = function ($entry, $type) {
37▕ if ($entry instanceof Exception) {
38▕ $entry = $entry->getMessage();
39▕ } ➜ 40▕ trigger_error($entry, $type);
41▕ };
42▕ }
When I remove this
#OA\JsonContent(ref="#/components/schemas/UserResource")
it works, but the user data is not displayed, maybe I should only return the token, and make another request with the token to get the information about the logged user. What can I do?, thanks
EDIT:
#OA\Response(
* response="200",
* description="An example resource",
* #OA\JsonContent(
* type="object",
* #OA\Property(
* format="string",
* default="20d338931e8d6bd9466edeba78ea7dce7c7bc01aa5cc5b4735691c50a2fe3228",
* description="token",
* property="token"
* ),
* #OA\Property(
* format="application/json",
* property="user",
* #OA\JsonContent(ref="#/components/schemas/UserResource")
* )
* ),
* )
I tried this, but it shows errors
Pretty close except...
use of 'format' instead of 'type'
you do not have to specify the content type if your property is already wrapped in #OA\JsonContent
you need to be careful with surplus trailing ','; doctrine can be picky with that
Here is my take which does work stand-alone (except for the missing #OA\Info):
<?php
use OpenApi\Annotations\OpenApi as OA;
/**
* #OA\Schema
*/
class LoginRequest{}
/**
* #OA\Schema
*/
class UserResource{}
/**
* Handle an incoming authentication request.
*
*
* #OA\Post(
* tags={"UnAuthorize"},
* path="/login",
* summary="User Login",
* #OA\RequestBody(
* #OA\MediaType(
* mediaType="application/json",
* #OA\Schema(
* type="object",
* ref="#/components/schemas/LoginRequest"
* )
* )
* ),
* #OA\Response(
* response="200",
* description="An example resource",
* #OA\JsonContent(
* type="object",
* #OA\Property(
* type="string",
* default="20d338931e8d6bd9466edeba78ea7dce7c7bc01aa5cc5b4735691c50a2fe3228",
* description="token",
* property="token"
* ),
* #OA\Property(
* property="user",
* ref="#/components/schemas/UserResource"
* )
* )
* ),
* #OA\Response(response="401", description="fail")
* )
*
*/
class Controller {}
The JsonContent you removed should be a property on the first JsonContent I think
I am trying to create an API for the sendOTP function created in the controller. The package I'm using to do so is DarkaOnLine/L5-Swagger which generates swagger UI based on OpenApi 3.0. I am new to Laravel Swagger API and the problem is with validations. I have 2 fields that are supposed to be validated country_code & mobile. I pass the $request parameter to the LoginRequest to validate the data. Below are my controller and request code.
LoginController
/**
* #OA\POST(
* path="/api/sendLoginOTP",
* operationId="sendLoginOTP",
* tags={"LoginviaOTP"},
* summary="Send Otp to mobile lstest",
* description="Sends Otp to Mobile and Returns mobile number and country code with default country code",
*
* #OA\Parameter(
* name="country_code",
* description="country code",
* required=true,
* in="path",
* #OA\Schema(
* type="string"
* )
* ),
* #OA\Parameter(
* name="mobile",
* description="mobile number",
* required=true,
* in="path",
* #OA\Schema(
* type="integer"
* )
* ),
* #OA\Response(
* response=200,
* description="successful operation"
* ),
* #OA\Response(response=400, description="Bad request"),
* #OA\Response(
* response=401,
* description="Unauthenticated",
* ),
* #OA\Response(response=404, description="Resource Not Found"),
* security={
* {
* "oauth2_security_example": {"write:projects", "read:projects"}
* }
* },
* )
*/
public function sendOTP(LoginRequest $request)
{
return response()->json('Validated');
}
LoginRequest
public function authorize()
{
return true;
}
public function rules()
{
return [
'country_code' => [
'required',
'exists:countries,iso',
'exists:users,country_code',
],
'mobile' => [
'required',
'numeric',
'exists:users,mobile',
],
];
}
Swagger UI
Output I get After Entering Credentials
JSFIDDLE of whole output I am getting
Output am expecting
My problem: whenever I am trying to validate the parameters it's not getting validated. I am not sure where am I going wrong here. Am I not supposed to pass $request to LoginRequest? if not this method then how am I supposed to validate the data provided in the parameters?
I just changed the in value of parameters from path to query and it worked well for me
/**
* #OA\Parameter(
* ....
* in="query",
* ....
* ),
* #OA\Parameter(
* ....
* in="query",
* ....
* ),
*/
I mount my swagger api documentation (with login to protect my route of "api/documentation"). The documentation UI it's ok but when i want execute "try it out"... Ups! Something going wrong...
I found that the class "Authenticate" (extends Middleware) redirect to login if not find the header this.headers['Content-Type'] = 'application/json';. Then, i gone to the view (resources/view/vendor/l5-swagger/index.blade.php) and set the correct headers:
requestInterceptor: function() {
this.headers['Authorization'] = 'Bearer '+token;
this.headers['Content-Type'] = 'application/json';
this.headers['Accept'] = 'application/json';
return this;
}
The problem it's that when i "retry it out" the result it's a redirect to login again. And i pass the headers on the curl:
curl -X GET "http://127.0.0.1:8000/api/mediador/xxx" -H "accept: */*" -H "Authorization: Bearer tokenGenerated" -H "Content-Type: application/json" -H "Accept: application/json"
Here an example that how i documentate my calls at the comments:
/**
* Insertamos un nuevo mediador
* #param Request $request
* #return \Illuminate\Http\JsonResponse Respuesta formateada para la api del create
*
* #OA\Post(
* path="/api/mediador/",
* tags={"Mediador"},
* description="Insert data from mediador profile",
* #OA\RequestBody(
* required=true,
* #OA\MediaType(
* mediaType="application/json",
* #OA\Schema(
* type="object",
* required={"id_user_crm","email","nombre_usuario"},
* #OA\Property(
* property="id_user_crm",
* description="ID from sugar ",
* type="string"
* ),
* #OA\Property(
* property="email",
* description="Email from profile",
* type="string"
* ),
* #OA\Property(
* property="nombre_usuario",
* description="Name of user",
* type="string"
* )
* )
* )
* ),
* #OA\Response(response="200", description="This is ok"),
* #OA\Response(response="401", description="Not logged with OAUTH token"),
* #OA\Response(response="403", description="Wrong data or duplicated fields in DataBase"),
* )
Why redirect to login yet? How can i set the data
i found the solution from my problem:
Swagger try read as html if you doesn't give the Response with correct "mediaType". Here put a complete comment to work with Swagger ui:
/**
* #OA\Post(
* path="/api/mediador/",
* tags={"Mediador"},
* description="Insert data from mediador profile",
* #OA\RequestBody(
* required=true,
* #OA\MediaType(
* mediaType="application/json",
* #OA\Schema(
* type="object",
* required={"id_user_crm","email","nombre_usuario"},
* #OA\Property(
* property="id_user_crm",
* description="ID outside of this platform",
* type="string"
* ),
* #OA\Property(
* property="email",
* description="Email from profile",
* type="string"
* ),
* #OA\Property(
* property="nombre_usuario",
* description="Name of user",
* type="string"
* )
* )
* )
* ),
* #OA\Response(
* response="200", description="Inserted data from mediador profiles",
* content={
* #OA\MediaType(
* mediaType="application/json",
* #OA\Schema(
* #OA\Property(
* property="id",
* type="integer",
* description="The id generated"
* ),
* #OA\Property(
* property="id_user_crm",
* type="integer",
* description="The reference id with the other platform"
* )
* )
* )
* }
* ),
* #OA\Response(response="401", description="Not logged with OAUTH token"),
* #OA\Response(response="403", description="Wrong data or duplicated fields in DataBase"),
* )
*/
With this comment before the function, read the #OA\Response and search #OA\MediaType to know what type of response returns the API REST.
I am using laravel 5.2.* and i am using darkaonline/l5-swagger : ~3.0 for the API's Documentation. I am sending parameters in header body and when I see the Swagger UI its shows me like below.
Data Type undefined
See below image for more details.
/**
* #SWG\Post(
* path="/api/v1/compaign_attr",
* summary="List compaign attributes",
* #SWG\Parameter(
* name="campaign_id",
* in="body",
* description="ID to fetch the targeted compaigns",
* required=true,
* #SWG\Property(property="request", type="json", example={ "campaign_id": 818, "code":"PLATFORM", "type":"Message"} )
* ),
* #SWG\Parameter(
* name="x-api-key",
* in="header",
* description="api key validation",
* required=true,
* type="string",
* ),
* #SWG\Response(response=200, description="successful operation", #SWG\Property(property="result", type="json", example={ "aa": { "bb", "cc" } } )),
* #SWG\Response(response=401, description="not authorized"),
* #SWG\Response(response=500, description="internal server error")
* )
*
*/
L5-Swagger does not have data type json. You need to set your parameter schema as object through swagger definition or inline schema.
* #SWG\Parameter(
* in="body",
* name="body",
* required=true,
* description="ID to fetch the targeted campaigns.",
* #SWG\Schema(
* #SWG\Property(property="campaign_id", type="integer", example=818),
* #SWG\Property(property="code", type="string", example="PLATFORM"),
* #SWG\Property(property="type", type="string", example="Message")
* ),
* )
This his how it looks.