How to combine a property and json response in Laravel + Swagger? - laravel

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

Related

Laravel Swagger PHP Couldn't find constant array

darkaonline/l5-swagger: 8.0.2
PHP Version: 7.3.13
zircote/swagger-php: 3.1.0
OS: Windows
I created a Contract ref object.
Now in my ContractController I want to list an array of contracts.
How can I do it?
I got this error Couldn't find constant array when trying to add type=array in OA\Items
/**
* #OA\Info(title="Contract API", version="1")
*/
class ContractController extends Controller
{
/**
* #OA\Post(
* path="/api/v1/contract/list",
* tags={"contact"},
* summary="List Contract",
* operationId="list",
* #OA\Parameter(
* name="keyword",
* in="path",
* description="keyword to search contracts",
* required=false,
* #OA\Schema(
* type="string"
* )
* ),
* #OA\Parameter(
* name="lang_code",
* in="path",
* description="lang_code define language client used",
* required=false,
* #OA\Schema(
* type="string",
* )
* ),
* #OA\Response(
* response=200,
* description="successful",
* #OA\JsonContent(
* #OA\Items(
* type=array, #This is where I got the error
* ref="#/components/schemas/Contract"
* )
* )
* ),
* #OA\Response(
* response=400,
* description="Wrong"
* )
* )
*/
public function list(Request $request)
{
$contracts = Contract::factory()->count(10)->make();
return response()->json([
'message' => 'good',
'contracts' => $contracts
], 200);
}
}
/**
* #OA\Schema(
* description="Contract model",
* type="object",
* title="Contract model"
* )
*/
class Contract extends Model
{
use HasFactory;
/**
* The unique identifier of a product in our catalog.
*
* #var integer
* #OA\Property(format="int64", example=1)
*/
public $id;
/**
* #var string
* #OA\Property(format="string", example="contract 001")
*/
public $contract_title;
}
Use type="array", (with "s) instead of type=array,
I know its late but
Try to use
* #OA\MediaType(
* mediaType="application/json",
* #OA\Schema(
* type="array",
* #OA\Items(
* ref="#/components/schemas/Contract"
* ),
* )
* )
Insead of #OA\JsonContent

How can send multipart/form-data file in application/json in swagger php

I want to uplaod a file in swagger-php in the json requestBody How can upload with the help of
swagger anonations
Trying from lot of hours but not luck how can send and file in application/json array Can you help if any
information about this so then i will solve my problem i have not concept about this
when this code generate in the terminal also not have any error and not shown in the request body in the swagger ui
/**
* #OA\Post(
* path="/products/save",
* tags={"Product"},
* summary="Post bulk products",
* description="Return bulk products",
* #OA\RequestBody(
* required=true,
* description="Bulk products Body",
* #OA\JsonContent(
* #OA\Property(
* property="products",
* #OA\Items(
* #OA\Property(property="first_name", type="string"),
* #OA\Property(property="last_name", type="string"),
* #OA\Property(property="email", type="string"),
* #OA\Property(property="phone", type="string"),
* #OA\MediaType(
* mediaType="multipart/form-data",
* #OA\Schema(
* #OA\Property(
* property="resume",
* type="file",
* format="file"
* ),
* )
* )
* ),
* )
* )
* ),
* )
*/
#OA\RequestBody(
#OA\MediaType(
mediaType="multipart/form-data",
#OA\Schema(
allOf={
#OA\Schema(ref="#components/schemas/item"),
#OA\Schema(
#OA\Property(
description="Item image",
property="item_image",
type="string", format="binary"
)
)
}
)
)
),

How to upload a file in swagger-php array

I want to uplaod a file in swagger-php in the json requestBody How can upload with the help of swagger anonations
Trying from lot of hours but not luck how can send and file in application/json array Can you help if any information about this so then i will solve my problem i have not concept about this
when this code generate in the terminal also not have any error and not shown in the request body in the swagger ui
/**
* #OA\Post(
* path="/products/save",
* tags={"Product"},
* summary="Post bulk products",
* description="Return bulk products",
* #OA\RequestBody(
* required=true,
* description="Bulk products Body",
* #OA\JsonContent(
* #OA\Property(
* property="products",
* #OA\Items(
* #OA\Property(property="first_name", type="string"),
* #OA\Property(property="last_name", type="string"),
* #OA\Property(property="email", type="string"),
* #OA\Property(property="phone", type="string"),
* #OA\Property(property="resume", type="string", format="base64"),
* ),
* )
* )
* ),
* )
*/
I want to this type of swagger-ui body so that user can fill attribut and
the resume add in base64 format
{
"products": [
{
"first_name": "string",
"last_name": "string",
"email": "string",
"phone": "string",
"resume": "string" ==> here i will send base64 format of resume file
}
]
}
``
You may use #OA\Property(property="file", type="string", format="binary"), to define a file property:
/**
* #OA\Schema(
* schema="ProductRequest",
* required={"products"},
* #OA\Property(
* property="products",
* type="array",
* #OA\Items(
* #OA\Property(property="first_name", type="string"),
* #OA\Property(property="last_name", type="string"),
* #OA\Property(property="email", type="string"),
* #OA\Property(property="phone", type="string"),
* #OA\Property(property="resume", type="string", format="binary"),
* ),
* )
* )
*/
Then you have to set a media type on your RequestBody using #OA\MediaType:
/**
* #OA\RequestBody(
* request="Product",
* required=true,
* description="Bulk products Body",
* #OA\MediaType(
* mediaType="multipart/form-data",
* #OA\Schema(ref="#/components/schemas/ProductRequest")
* )
* )
*/
And finally on your #OA\Post:
/**
* #OA\Post(
* path="/products/save",
* tags={"Product"},
* summary="Post bulk products",
* description="Return bulk products",
* #OA\RequestBody(ref="#/components/requestBodies/Product"),
* #OA\Response(response=200, ref="#/components/responses/Product")
* )
*/
See also Swagger docs on File data type and File upload for more info.
Update: If you don't want separate declarations just merge them like this:
/**
* #OA\Post(
* path="/products/save",
* tags={"Product"},
* summary="Post bulk products",
* description="Return bulk products",
* #OA\RequestBody(
* required=true,
* description="Bulk products Body",
* #OA\MediaType(
* mediaType="multipart/form-data",
* #OA\Schema(
* #OA\Property(
* property="products",
* type="array",
* #OA\Items(
* #OA\Property(property="first_name", type="string"),
* #OA\Property(property="last_name", type="string"),
* #OA\Property(property="email", type="string"),
* #OA\Property(property="phone", type="string"),
* #OA\Property(property="resume", type="string", format="binary"),
* )
* )
* )
* )
* )
* )
*/
You may also want an approach with PHP classes
So you can define a model like that:
/**
* #OA\Schema(
* schema="User",
* required={"first_name", "last_name" // and so on}
* )
*/
class User
{
/**
* #OA\Property(type="string")
*/
public $first_name;
/**
* #OA\Property(type="string")
*/
public $last_name;
// add your other fields bellow
}
after you can define for example the body of a POST request as follows:
<?php
/**
* #OA\Schema(
* schema="CreateUsers",
* required={"users"}
* )
*/
class CreateUsers
{
/**
* #var array
* #OA\Property(ref="#/components/schemas/User")
*/
public $users;
}
And lastly create the your Request in your documentation for example:
/**
* #OA\Post(
* path="YOUR ROUTE URL",
* operationId="createUsers",
* tags={"Users"},
* #OA\RequestBody(
* required=true,
* #OA\MediaType(
* mediaType="application/json",
* #OA\Schema(ref="#/components/schemas/CreateUsers")
* )
* ),
* summary="Create a collection of users",
* description="Create a collection of users"
* )
**/
EDIT 1:
If you want a request that have a file to the request body you way do:
/**
* #OA\Post(
* path="YOUR ROUTE URL",
* operationId="createUsers",
* tags={"Users"},
* #OA\RequestBody(
* required=true,
* #OA\MediaType(
* mediaType="multipart/form-data", // here we need to change from "application/json" to "multipart/form-data" in order to make our file visible
* #OA\Schema(ref="#/components/schemas/CreateUsers")
* )
* ),
* summary="Create a collection of users",
* description="Create a collection of users"
* )
**/
And make your field in your PHP class:
/**
* #OA\Schema(
* schema="User",
* required={"first_name", "last_name", "file" // and so on}
* )
*/
class User
{
/**
* #OA\Property(type="string")
*/
public $first_name;
/**
* #OA\Property(type="string")
*/
public $last_name;
/**
* #OA\Property(description="file to upload", type="string", format="file")
*/
public $file;
// add your other fields bellow
}
You can see an example here: swagger-php/Examples/petstore.swagger.io/controllers/PetController.php

Array of objects in Swagger

I am new to Swagger. I am using DarkaOnline Swagger UI (OAS3).
I have a JSON request body like this
{
"CurrentPuzzle": "1",
"OpenedLevel": "10",
"RewardPuzzlePiecess":
[
1,
2,
]
}
I need to define this in swagger model. What I tried so far is I defined the following in swagger controller :
/**
* #OA\Post(path="/gameData",
* tags={"user"},
* summary="Add Game Data of User",
* security={{"bearerAuth":{}}}, *
* description="",
* operationId="gameData",
* #OA\RequestBody(
* required=true,
* description="Created user object",
* #OA\JsonContent(
* type="object",
* #OA\Items(ref="#/components/schemas/Game")
* )
* ),
* #OA\Response(response="default", description="successful operation")
* )
*/
public function gameData()
{
}
In Game Model :
/**
* #OA\Property(
* type="object",
* #OA\Items(
* #OA\Property(
* type="integer",
* description="The puzzle",
* #OA\Schema(type="array")
* ),
* #OA\Property(
* type="integer",
* description="The level",
* #OA\Schema(type="integer")
* ),
* #OA\Property(
* type="array",
* description="The survey ID",
* #OA\Items(
* type="string",
* ),
* #OA\Schema(type="array")
* ),
* ),
* description="Store User Survey Results"
* )
* #var array
*/
public $SurveyDataList;
After running, I am getting only an empty object in swagger ui like this {}.
I found the solution ,
in my controller I defined my gameData function like this,
/**
* #OA\Post(path="/gameData",
* tags={"user"},
* summary="Add Game Data of User",
* security={{"bearerAuth":{}}}, *
* description="",
* operationId="gameData",
* #OA\RequestBody(
* required=true,
* description="Created user object",
* #OA\JsonContent(
* ref="#/components/schemas/Game"
* )
* ),
* #OA\Response(response="default", description="successful operation")
* )
*/
public function gameData()
{
}
And in model.. I defined 3 properties where two of them are of type numbers and thirs one as array with Items in it.
/**
* #OA\Property(
* property="CurrentPuzzle",
* type="number",
* enum="1",
* description="Store current puzzle"
* )
*/
/**
* #OA\Property(
* property="OpenedLevel",
* type="number",
* enum="1",
* description="Store current level"
* )
*/
/**
* #OA\Property(
* property="RewardPuzzlePiecess",
* type="array",
* * #OA\Items(
* type="number",
* description="The survey ID",
* #OA\Schema(type="number")
* ),
* description="Store reward index"
* )
*/

Laravel (Post, Delete, Put) routes in Swagger

I have update the code for get method as follows which working properly
in swagger.
Can any one please suggest me the swagger code for post, put, delete with its laravel route, controller code. (As I mention follows for GET)
route/web.php
Route::group(['prefix' => 'api/'], function () {
Route::get('dashboard', 'DashboardController#index');
});
DashboardController.php
* Display a listing of the resource.
*
* #return \Illuminate\Http\JsonResponse
*
* #SWG\Get(
* path="/api/dashboard",
* description="Returns dashboard overview.",
* operationId="api.dashboard.index",
* produces={"application/json"},
* tags={"dashboard"},
* #SWG\Response(
* response=200,
* description="Dashboard overview."
* ),
* #SWG\Response(
* response=401,
* description="Unauthorized action.",
* )
* )
*/
public function index(Request $request)
{
return response()->json([
'result' => [
'statistics' => [
'users' => [
'name' => 'Name',
'email' => 'user#example.com'
]
],
],
'message' => '',
'type' => 'success',
'status' => 0
]);
}
Bellow laravel routes for swagger Post/Put/Delete.
Route::post('/api/user', 'DashboardController#store');
Route::put('/api/user/{user_id}', 'DashboardController#edit');
Route::delete('/api/user/{user_id}', 'DashboardController#delete');
Route::get('/api/users', 'DashboardController#getData');
Route::get('/api/user/{user_id}', 'DashboardController#getDataById');
For Post
/**
* #SWG\Post(
* path="/api/user",
* tags={"User"},
* operationId="ApiV1saveUser",
* summary="Add User",
* consumes={"application/x-www-form-urlencoded"},
* produces={"application/json"},
* #SWG\Parameter(
* name="name",
* in="formData",
* required=true,
* type="string"
* ),
* #SWG\Parameter(
* name="phone",
* in="formData",
* required=true,
* type="number"
* ),
* #SWG\Response(
* response=200,
* description="Success"
* ),
*/
For Put
/**
* #SWG\Put(
* path="/api/user/{user_id}",
* tags={"User"},
* operationId="ApiV1UpdateUser",
* summary="Update User",
* consumes={"application/x-www-form-urlencoded"},
* produces={"application/json"},
* #SWG\Parameter(
* name="user_id",
* in="path",
* required=true,
* type="string"
* ),
* #SWG\Parameter(
* name="name",
* in="formData",
* required=true,
* type="string"
* ),
* #SWG\Response(
* response=200,
* description="Success"
* ),
*/
For Delete By ID
/**
* #SWG\Delete(
* path="/api/users",
* tags={"User"},
* operationId="ApiV1DeleteUser",
* summary="Delete User",
* #SWG\Parameter(
* name="user_id",
* in="path",
* required=true,
* type="string"
* ),
* #SWG\Response(
* response=200,
* description="Success"
* ),
*/
For Get
/**
* #SWG\Get(
* path="/api/users",
* tags={"User"},
* operationId="ApiV1GetUsers"
* summary="Get Users",
* #SWG\Response(
* response=200,
* description="Success"
* ),
*/
For Get By ID
/**
* #SWG\Get(
* path="/api/user/{user_id}",
* tags={"User"},
* operationId="ApiV1GetUserById",
* summary="Get User by user id",
* #SWG\Parameter(
* name="user_id",
* in="path",
* required=true,
* type="string"
* ),
* #SWG\Response(
* response=200,
* description="Success"
* ),
*/
I have found code parameters for post, delete routes at following link
https://github.com/zircote/swagger-php/tree/master/Examples

Resources