Best approach for API Versioning - api

What is the best way to version API?
For example I am using sails js for API backend, to version the API:
Should it be done in my application, (in the controller) (at app level)?
Should I use the routes.js for versioning the API (framework level)?
Should I do it with nginx (server level)?
Should it be done at API Gateway (API Management)?

My approach for api versioning is at application level:
Create subfolder for your controllers as:
/controllers/v1/UserController.js
/controllers/v2/UserController.js
In your routes.js file, add as follow:
'POST /api/v2/user': 'v2/UserController.create',
'POST /api/v1/user': 'v2/UserController.create',
And in your policies.js, you can add middlewares like this:
'v2/UserController': {
'create': ['isAuthenticated','isAuthorized']
}
My current sails' version is: 0.12.3.
At this time, model versioning is not supported by using subfolders.

Related

Auth::user() returns null with the user logged in but works in blade template

I am using Laravel 6 and in the controller store method, Auth::user() returns null even when the user is logged in but works in blade template. I have gone through similar questions but nothing is working.
I am posting to an API route and I am not sure whether this is the reason. Kindly assist.
If you have not adjusted the api web group or the RouteServiceProvider that comes with the default application you will not have any session support in your API routes (routes/api.php). The APIs are usually stateless so no session support. If you want to deal with authentication using the built in authentication system you would want to deal with a token based system. The default api guard that is setup for you will use the TokenGuard which will look in the request for a token being passed to authenticate the user against. You would need to assign the middleware auth with the parameter api, to specify the api guard, auth:api.
If you send a request correctly to one of these end points now, including the token, you will have a user returned from Auth::user() or $request->user() etc.
Laravel 6.x Docs - API Authentication - Passing Tokens in Requests
Laravel 6.x Docs - API Authentication - Protected Routes auth:api
Pleease read the whole section for a better understanding of using this type of Guard with the built in Authentication system:
Laravel 6.x Docs - API Authentication
If you don't want to deal with a "stateless" API, and you would rather use sessions you can just move your API routes to the web.php file and prefix them with api.

Generating OpenAPI definitions and documentation for an existing flask project

I'm trying to integrate an existing flask app with OpenAPI (Swagger), to generate its documentation and use Swagger UI. How should I do this?
The best solution (expected behaviour with least changes) for me was to use connexion, and use OpenAPI Specifications to replace the routes layer. Instead of using Flask "directly", a connection app was created.
app = connexion.App(__name__, specification_dir='swagger/')
app.add_api('my_api.yaml')
app.run(port=8080)
https://github.com/zalando/connexion

Sharing the same code between several versions of the same Meteor web

I have a Meteor web deployed with Phusion Passenger integrated with Apache. The users access it with http://mycompany.org:3001.
That Meteor web communicates, via REST API, with another external server.
That external server has 3 versions of the same REST API:
http://external_server/v1/restapi
http://external_server/v2/restapi
http://external_server/v3/restapi
Each version of the above REST API manages a different user database, i.e. user_DB_1 -> v1, user_DB_2 -> v2, user_DB_3 -> v3.
Currently, my deployed Meteor web is making calls to the v1 of that REST API (http://external_server/v1/restapi).
Now, I have to call the other versions of the REST API (v2 and v3) with the same Meteor web, like this:
http://mycompany.org:3001/meteor_web_v1 (currently http://mycompany.org:3001)
http://mycompany.org:3001/meteor_web_v2
http://mycompany.org:3001/meteor_web_v3
Is it possible to capture the version of that URL and pass it as parameter to the Meteor web so that it calls the corresponding API?
For example, if the user make HTTP requests to http://mycompany.org/meteor_web_v1/login, then the web calls to http://external_server/v1/restapi, and so on...
Which is the approach here? Using maybe Apache mod_rewrite, Iron Router or which solution?
You can use either flow router or iron router to give you the url part as a parameter, you name it like this in your route declaration:
'/:myroute'
and then you will get a route parameter as a variable which you can use in your code to pass to your server method to do the http request.
You are doing the http request from the server, right ? Doing it that way prevents any CORS problems, and offloads the waiting to the server. The server should then update the database wth the received data, and the client will auto-refresh to make the results available.

Why create a separate application for RESTful API?

In the guide for Yii 2 it is said:
While not required, it is recommended that you develop your RESTful
APIs as a separate application, different from your Web front end and
back end for easier maintenance.
Source: RESTful Web Services - Quick Start
What does this mean? Would this be a completely different application or can it be in the same folder as the 'normal' web application? I've just started with my application so I can change things easily, more or less. But I'm wondering: if I would create another application than my business logic would not be accessible.
Why and how I should create another application? And when it's not required?
It means you have to create an application like frontend or backend(Yii 2 advanced application template),
what you have to do is create another directory call 'api' same as backend or frontend, and it'll contain folder structure same as backend|frontend except assets, views, widgets etc.
Basically you need folder structure like this
api
-config
-modules
--v1
---controllers
---models
-runtime
-tests
-web
backend
common
console
environments
frontend
If you'r going to use Yii 2 basic application template to develop rest api, it's posible. create module call 'api' and create a sub directory call 'v1' as sub-module.
(Yii doc -A module may consist of sub-modules.)(GiovanniDerks - backend sub-modules)
-modules
--api
---v1
----controllers
----models
There is an advantage of using one of these folder structure, because you don't have to worry about route much.
https://domain.com/api/v1/products
Here is good example for RESTful API with advance template
Setup RESTful API in Yii2(budiirawan)
API & RESTFull API are different. RESTFull APIs have to have REST standards. basically that's why APIs are developed as separate application. in normal app, we create 4 actions for CRUD functions. but in yii2 RESTFull API we just create One action for all CRUD functions. (Controllers extend from REST Active Controller - yii\rest\ActiveController ). in core code you can find find 4 actions for different headers GET,POST,PUT & DELETE .
'index' => ['GET', 'HEAD'],
'view' => ['GET', 'HEAD'],
'create' => ['POST'],
'update' => ['PUT', 'PATCH'],
'delete' => ['DELETE'],
for authentication basically we can use 'HTTP Basic Authentication'
This article explain the idea and the why , also it provide you a starter project called "yii2-advanced-api": http://budiirawan.com/setup-restful-api-yii2/
IMHO if you need REST API for Angular.js or Knockout.js AJAX calls on your website it's an overhead to do it as a separate application. Because you will have issues with cross-domain AJAX calls (especially for POST requests).
I think it's enough to make a module (API) in the frontend for REST API

configure restful routes in rails

I am trying to create a restful web service in a rails application. I need to configure a restful routes as below.
localhost:3000/books/<book_name>/new/<parameters to create Book Item>
Eg: http://localhost:3000/books/sherlock/new/id/123/business/<BU>/.../{other parameters}
How do I configure it in the routes and access the params in controller. Please help.
This technique is called "route globbing".
http://guides.rubyonrails.org/routing.html#route-globbing-and-wildcard-segments
However, if I were you - I'd used "default" query params. For many reasons.