API - D4uS1/ez-on-rails GitHub Wiki
API
The API endpoints for your application that were generated using the ezapi generator are available over the api namespace.
The generator uses rswag to generate tests and openAPI specs automaticly. The openAPI specifications can be requested by calling your-base.domain/api-docs. Details of the openAPI documentation and how you can change them are explained in the [openAPI section](## OpenAPI Documentation).
In case you want to do breaking changes to your apis and your clients should not be able to expect the old behavior, there is an api version defined constant you can control. See the [api version section](## API Version) for details.
If you generated an endpoint to a resource that were generated using the ezscaff generator, the endpoint will have the default rest actions and additionally will have a search action. The search action is explained in the [search and filters section](## Search and Filters) in detail. All other actions can be called like you know it from rails.
The generator creates an access restriction for the permission system by default. Hence initial all actions are only accessible for signed in users. You can change the access restrictions or delete them to make the endpoints public by just editing the db/seeds.rb file.
The [authentication](## Authentication) sections shows the ways to authenticate the users.
Note that all requests to the api are expected to be in JSON format. If you do not pass the header 'ACCEPT': 'application/json' your request will be not accepted using the not acceptable http response (406).
Ez-on-rails has some build in api actions out of the box. Those can eg. return user information or handle direct upload. See the [existing api actions](## Existing API actions) section for details.
You can use the ez-on-rails-react npm package to call your api from a react application. This package provides forms like an registration or login form and provides some http clients to request your api without pain.
OpenAPI Documentation
The ezapi generators generates entries for your requested endpoints in the openAPI documentation using rswag.
To change the documentation, you need to change the integration spec file that was generated using the api generator. Refer to the rswag documentation for detailed information about its DSL and how to change them.
If you generated a REST endpoint for some resource, the ezapi generator created two schema entries in the spec/swagger_helper.rb file. Those schemas are used inside the integration spec to generate the parameters and results documentation.
- The generated Properties schema holds all properties except the id, created_at, updated_at and owner of the model. This is used to describe eg. update and create parameters.
- The schema inherits from the properties schema and adds the excluded fields by adding all from the EzOnRailsRecord schema
Beside the EzOnRailsRecord schema, that holds id, created_at, updated_at and owner properties, there are two other schemas you should know about:
- The RailsFileBlob schema is used for direct uploading files
- The UserProfile schema is used for the existing api actions for the own user management, see [existing api actions](## Existing API actions) for details
- The SearchFilter and SearchFilterComposition schemas are used for search actions, see [search and filters](## Search and Filters) for details
The ezapi last step is updating the openAPI spec. If you changed something or want to regenerate the openAPI, you have to call:
rails rswag:specs:swaggerize
Now the updated api documentation can be requested by the /api-docs path.
API Version
The ezapp generator creates the initializer config/initializers/api.rb that holds the constant API_VERSION. This constant holds some string of the api version your api is currently running on.
This version is used by every action to check the current version against the clients requested version. If this versions do not match, the request will return the http status code gone (410).
Therefore every api request needs to have the api-version header variable.
This enables you to prevent clients from calling api actions that were recently changed. Your client needs to take care about this and request an application update to be able to request the api again.
Search and Filters
If you generated some api endpoints using the ezapi generator that targets a resource you previously generated using the ezscaff generator (using the --resource argument), a search action will be created beside the default REST actions.
This search action enables you to request a set of records matching a passed filter.
The schemas SearchFilter and SearchFilterComposition describing the filters for the openAPI spec are generated in the spec/swagger_helper.rb file. Those schemas are used for the openAPI search endpoint documentation.
You can search for values directly, by passing the filter parameter that holds something like the following example:
filter: {
field: 'name',
operator: 'contains',
value: 'development'
}
This will return all records of your target REST endpoint that names contain the value 'development'.
The field parameter holds the name of the field the operator should be applied to with the specified value. The following operators are possible:
- eq - equals
- neq - equals not operator
- isnull - is null
- isnotnull - is not null
- lt - less than
- lte - less than or equal
- gt - greater than
- gte - greater than or equal
- contains - contains
- doesnotcontain - does not contain
- isempty - is empty
- isnotempty - is not empty
You can also combine filters, for example:
filter: {
logic: 'and',
filters: [
{
field: 'name',
operator: 'contains',
value: 'development'
},
{
field: 'created_at',
operator: 'gt',
value: '2022-01-01'
}
]
This will return all records of your target REST endpoint that names contain the value 'development' that were created after 2022-01-01.
The logic parameter can connect the filters using and or or.
The search is executed using the scoped_search. The allowed searchable fields are all fields of your model. Those are defined by the following line of code you can find in your generated model class:
scoped_search on: self::search_keys
If you want to change the searchable fields, you must overwrite the class method search_keys or provide the fields on your own. You can also make use of everything you need to change the behavior of your search. Just refer to the scoped_search documentation to see whats possible.
Tipp: Beside the filter parameter, you can also pass page and page_size to the default search actions to paginate the results. You can also add order and order_direction parameters to sort the results. page is zero based. The first page is zero. page_size is one based. This is the same behavior like on arrays. The order direction can be asc or desc and the order field any attribute of your model.
Authentication
Ez-on-rails provides two ways to sign into the api, bearer and oauth.
Bearer
The bearer authenication is done by devise token auth. However the behavior of device_token_auth to create new tokens on every request is disabled in the config/device_token_auth.rb initializer that was created using the ezapp generator.
The bearer authentication does not need some additional work like defining oauth clients. You just need the email and password of the user who wants to sign in.
Authentifikation
To get the bearer token information, you need to call a POST request to /api/auth/sign_in. The request must be in JSON format and must have the following values:
- password
The endpoint returns the authentication information needed by further requests in the headers. Those values given by the headers are:
- uid
- access-token
- client
All three values must be provided by the following requests to authenticate the user for api requests.
OAuth
Ez-on-rails provides you with the ability to use existing oauth clients or create your own oauth application. The default preinstalled oauth provider is the gitlab provider, it just needs to be activated by following the instructions of the next section.
Usage of the existing oauth applications
The ezapp generator creates the file config/initializers/devise_omniauth.rb. This file holds outcommented oauth presets for gitlab and email. The gitlab provider is used to authenticate against an oauth application you created on Gitlab. The email provider is used to authenticate against an own oauth application created via doorkeeper. See the [own oauth provider section](#### Own oauth provider) to see how you can create one.
As you can see in the initializer, we recommend to save the credentials for your applications in the rails credentials store. You need to provide them at the defined locations.
Example for Gitlab:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :gitlab,
Rails.application.credentials.omniauth[:gitlab][:uid],
Rails.application.credentials.omniauth[:gitlab][:secret],
scope: 'read_user'
end
You are free to add other oauth providers than gitlab or doorkeeper. The following sections give you some instructions how to do this.
Adding other oauth providers
To add other providers than gitlab or doorkeeper, perform the following steps:
- Search for a gem: The oauth implementation of ez-on-rails uses omniauth of devise. Hence you can find the most gems for oauth providers that uses this implementation here.
- Create the oauth application at the provider of your choise. We recommend to save the credentials in the rails credentials store.
- Create a new entry in the __config/devise_omniauth.rb file for your new provider.
- Optional, depending on your provider: Overwrite the from_omniauth(auth) class method of the User model. This method takes the auth information and creates the user from its information.
- Tip: You can use the (ezuser)[https://github.com/D4uS1/ez-on-rails/wiki/ezuser] generator to eject the user model. Just change the lines you need, but note: You need the provider and uid, otherwise devise_token_auth will not find the created user on authentication.
- Another tip: Delete everything else that was generated by the ezuser generator. This keeps everything else available in the ez-on-rails core.
Because we want the user to accept the privacy policy of your application, there exists a default redirect after successfull omniauth login to a page the user must accept the policy.
Authentifikation
After you signed in using oauth, you get an access token that must be passed using the authorization header for further requests.
Own oauth provider
Ez-on-rails uses dorrkeeper to provide the ability to create own oauth applications. If you call the path oauth/applications as super admin, you are able to create your applications here.
The callback value of your application must be __omniauth/email/callback
After you created your application and defined the correct callback, you must comment out the email provider that is provided in the config/initializers/devise_omniauth.rb file. This file was created by the ezapp generator. As you can see here, you need to define the credentials of your previously defined application. We recomment to add those credentials to the rails credentials store. Hence your entry should look something like that:
Rails.application.config.middleware.use OmniAuth::Builder do
...
provider :email,
Rails.application.credentials.omniauth[:email][:uid],
Rails.application.credentials.omniauth[:email][:secret],
scope: 'profile email'
end
You can now authenticate by calling the path api/auth/email.
The provider is called email, because we do not want some new user being created if you make use of your own provider.
Existing API actions
POST /api/active_storage/blobs/create_direct_upload
This action can be used to create direct uploads from your api. Rails provides a javascript package to make those direct uploads to work. This action was implemented to prevent the direct upload from being public. Read the active storage endpoints article for more details.
DELETE /api/active_storage/blobs/:signed_id
This action can be used to delete file blobs from your api. This action was implemented to prevent the direct upload from being public. Read the active storage endpoints article for more details.
GET /api/users/me
This action provides an endpoint to receive the own user information. Can be used by user editing forms. Please read the openAPI documentation of the application for details.
PUT /api/users/me
This action provides an endpoint to update the own user information. Can be used by user editing forms. Please read the openAPI documentation of the application for details.