diff --git a/README.md b/README.md index d8637a1..0a2303a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## Laravel-Portugal API +# Laravel-Portugal API ![Run tests](https://github.com/laravel-portugal/api/workflows/Run%20tests/badge.svg) [![Coverage Status](https://coveralls.io/repos/github/laravel-portugal/api/badge.svg?branch=master)](https://coveralls.io/github/laravel-portugal/api?branch=master) @@ -10,7 +10,7 @@ - PHP >= 7.4 - MySQL >= 8, MariaDB >= 10 or PostgreSQL >= 11 -**Steps to activate this project** +**Activation** 1. Clone this repository. 2. Run `composer install` to install all dependencies (add `--no-dev` if you're using this in production). @@ -18,21 +18,39 @@ 4. Update the `.env` file with a new `APP_KEY` and the connection details for the database. 5. Run `php artisan migrate` to create the database schema. -## Testing +**Deployment** -This project is fully tested. We have an [automatic pipeline](https://github.com/laravel-portugal/api/actions) and an [automatic code quality analysis](https://coveralls.io/github/laravel-portugal/api) tool set up to continuously test and assert the quality of all code published in this repository, but you can execute the test suite yourself by running the following command: +This project is prepared to be run with Docker. There are docker-compose files that try to provide an easy way to deploy this project to your infrastructure. You should create a `docker-compose.override.yml` (probably based on the example file provided), and change it to your specific needs. -``` bash -vendor/bin/phpunit -``` +## Documentation -_Note: This assumes you've run `composer install` (without the `--no-dev` option)._ +This service API is organized around REST and has predictable resource-oriented URLs, accepts form-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs. -**We aim to keep the master branch always deployable.** Exceptions may happen, but they should be extremely rare. +### Authentication -## Documentation +Authentication to the API is performed via checking for the presence of a Bearer token on the Authorization header of a request. This token is an encoded JWT that's generated by exchanging the username and the password, of a previously registered user account, on the `/login` endpoint. + +### Include relationship data + +Many objects allow you to request additional relationship information as an expanded response, by using the `include` request parameter. This parameter is available on all API requests that have related data available to be included and applies to the response of that request only. You can, however, include multiple objects at once by identifying multiple items in the `include` query parameter separated by a comma. + +### Errors + +This API uses conventional HTTP response codes to indicate the success or failure of a request. Codes in the `2xx` range indicate success, codes in the `4xx` range indicate a validation error (e.g., a required parameter was omitted) and codes in the `5xx` range indicate an error with the service internal programming (these should be very rare). Check the table below for a list of possible status codes and their meaning: + +Code | Status | Description +---- | ------ | ----------- +200 | OK | Everything worked as expected. +401 | Unauthorized | No valid authorization header value provided. +403 | Forbidden | The supplied authorization key doesn't have permission to perform the request. +404 | Not Found | The requested resource doesn't exist. +422 | Unprocessable Entity | The request was unacceptable, often due to missing a required parameter. +429 | Too Many Requests | Too many requests hit the API too quickly. +5xx | Server Errors | Something went wrong on the internal service programming. -Please see the [public documentation site](https://laravel-portugal.stoplight.io/docs/api/docs/1.Introduction.md). +## Support + +If you have any problems and need assistance, feel free to use the issue tracker to ask for support. However, be patient! Your request might take time to be answered. ## Changelog @@ -42,6 +60,18 @@ Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed re Please see [CONTRIBUTING](CONTRIBUTING.md) for details. +## Testing + +This project is fully tested. We have an [automatic pipeline](https://github.com/laravel-portugal/api/actions) and an [automatic code quality analysis](https://coveralls.io/github/laravel-portugal/api) tool set up to continuously test and assert the quality of all code published in this repository, but you can execute the test suite yourself by running the following command: + +``` bash +vendor/bin/phpunit +``` + +_Note: This assumes you've run `composer install` (without the `--no-dev` option)._ + +**We aim to keep the master branch always deployable.** Exceptions may happen, but they should be extremely rare. + ## Security Please see [SECURITY](SECURITY.md) for details. diff --git a/docs/1.Introduction.md b/docs/1.Introduction.md deleted file mode 100644 index b883b7d..0000000 --- a/docs/1.Introduction.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -tags: [Introduction] ---- - -# Introduction - -This service API is organized around REST and has predictable resource-oriented URLs, accepts form-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs. diff --git a/docs/2.Errors.md b/docs/2.Errors.md deleted file mode 100644 index cbf2b36..0000000 --- a/docs/2.Errors.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -tags: [Errors] ---- - -# Errors - -This API uses conventional HTTP response codes to indicate the success or failure of a request. Codes in the `2xx` range indicate success, codes in the `4xx` range indicate a validation error (e.g., a required parameter was omitted) and codes in the `5xx` range indicate an error with the service internal programming (these should be very rare). Check the table below for a list of possible status codes and their meaning: - -| Code | Status | Description | -| :--- | :------------------- | :----------------------------------------------------------------------------- | -| 200 | OK | Everything worked as expected. | -| 401 | Unauthorized | No valid authorization header value provided. | -| 403 | Forbidden | The supplied authorization key doesn't have permission to perform the request. | -| 404 | Not Found | The requested resource doesn't exist. | -| 422 | Unprocessable Entity | The request was unacceptable, often due to missing a required parameter. | -| 429 | Too Many Requests | Too many requests hit the API too quickly. | -| 5xx | Server Errors | Something went wrong on the internal service programming. | diff --git a/docs/api.v1.yaml b/docs/api.v1.yaml deleted file mode 100644 index f258733..0000000 --- a/docs/api.v1.yaml +++ /dev/null @@ -1,543 +0,0 @@ -openapi: 3.0.0 -info: - title: laravel-portugal/api - version: '1.0' - license: - name: MIT - url: 'https://github.com/laravel-portugal/api/blob/master/LICENSE.md' - description: API layer to support the public website of the Laravel-Portugal community - contact: - name: Developers - url: 'https://github.com/laravel-portugal/api/issues' -servers: - - url: 'https://api.laravel.pt' - description: Production - - description: Development - url: 'http://api.laravel.test' -paths: - /tags: - get: - summary: Listing all tags - responses: - '200': - description: OK - headers: {} - content: - application/json: - schema: - type: object - properties: - data: - type: array - items: - $ref: '#/components/schemas/Tag' - examples: {} - operationId: get-tags - description: List of all stored tags - parameters: [] - tags: - - Tags - /links: - get: - summary: Listing links - tags: - - Links - responses: - '200': - description: OK - content: - application/json: - schema: - type: object - properties: - data: - type: array - maxItems: 15 - items: - $ref: '#/components/schemas/Link' - links: - $ref: '#/components/schemas/Pagination' - operationId: get-links - description: List of a paginated set of stored links - post: - summary: Creating a new link - operationId: post-links - responses: - '204': - description: No Content - '422': - description: Unprocessable Entity - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '429': - description: |- - Too Many Requests - - When there's already five unapproved Link resources of a single author. - - Trusted User resources or User resources with ADMIN or EDITOR roles won't have any limit applied. - description: Store a new Link resource - requestBody: - content: - application/json: - schema: - type: object - properties: - link: - type: string - format: hostname - title: - type: string - description: - type: string - author_name: - type: string - author_email: - type: string - format: email - cover_image: - type: string - format: binary - description: An image file - tags: - type: array - description: An array of Tags' id - items: - type: integer - required: - - link - - title - - description - - author_name - - author_email - - cover_image - - tags - tags: - - Links - parameters: - - schema: - type: string - default: application/json - in: header - name: Content-Type - /accounts/users: - post: - summary: Create user accounts - operationId: post-accounts-users - responses: - '204': - description: No Content - '422': - description: Unprocessable Entity - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: Store a new User account - requestBody: - content: - application/json: - schema: - type: object - properties: - name: - type: string - description: '' - email: - type: string - format: email - password: - type: string - format: password - minLength: 6 - required: - - name - - email - - password - tags: - - Accounts - - Users - parameters: - - schema: - type: string - default: application/json - in: header - name: Content-Type - /discussions/questions: - post: - summary: Creating new questions - operationId: post-discussions-questions - responses: - '204': - description: No Content - '422': - description: Unprocessable Entity (WebDAV) - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: Store a new Question resource - security: - - ' Bearer Token': [] - requestBody: - content: - application/json: - schema: - type: object - properties: - title: - type: string - description: - type: string - required: - - title - - description - tags: - - Discussions - - Questions - parameters: - - schema: - type: string - default: application/json - in: header - name: Content-Type - /accounts/login: - post: - summary: Authenticating a user - operationId: post-accounts-login - responses: - '200': - description: OK - content: - application/json: - schema: - type: object - properties: - access_token: - type: string - description: The encoded JWT that authenticates the User - type: - type: string - default: bearer - description: '' - expired_in: - type: integer - '422': - description: Unprocessable Entity - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - tags: - - Accounts - - Login - description: Authenticates a User account - parameters: - - schema: - type: string - default: application/json - in: header - name: Content-Type - requestBody: - content: - application/json: - schema: - type: object - properties: - username: - type: string - format: email - password: - type: string - format: password - minLength: 6 - required: - - username - - password - /accounts/logout: - post: - summary: Logging out a user - operationId: post-accounts-logout - responses: - '200': - description: OK - security: - - ' Bearer Token': [] - description: Logs out the User by revoking the given bearer token - tags: - - Accounts - - Logout - parameters: [] - /accounts/me: - get: - summary: Show authenticated user details - tags: - - Accounts - - Users - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/User' - operationId: get-accounts-me - description: Shows details of the authenticated User - security: - - ' Bearer Token': [] - '/discussions/questions/{questionId}': - parameters: - - schema: - type: integer - name: questionId - in: path - required: true - patch: - summary: Updating a question - operationId: patch-discussions-questions-questionId - responses: - '204': - description: No Content - '403': - description: |- - Forbidden - - If the given Question resource ID isn't authored by the authenticated User. - '404': - description: |- - Not Found - - If the given Question resource ID isn't present in the database. - '422': - description: Unprocessable Entity - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - security: - - ' Bearer Token': [] - tags: - - Discussions - - Questions - description: Updates a given Question resource - parameters: - - schema: - type: string - default: application/json - in: header - name: Content-Type - requestBody: - content: - application/json: - schema: - type: object - properties: - title: - type: string - maxLength: 255 - description: - type: string - default: 'null' - required: - - title - '/discussions/questions/{questionId}/answers': - parameters: - - schema: - type: string - name: questionId - in: path - required: true - post: - summary: Creating an answer for a question - operationId: post-discussions-questions-questionId-answers - responses: - '204': - description: No Content - '404': - description: |- - Not Found - - If the given Question resource ID isn't present in the database. - '422': - description: Unprocessable Entity (WebDAV) - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - description: Store a new Answer resource associated to the given Question resource - security: - - ' Bearer Token': [] - requestBody: - content: - application/json: - schema: - type: object - properties: - content: - type: string - required: - - content - parameters: - - schema: - type: string - default: application/json - in: header - name: Content-Type - tags: - - Discussions - - Questions - - Answers -components: - schemas: - Tag: - description: A Tag resource's details - type: object - x-tags: - - Resources - - Tags - title: Tag - properties: - id: - type: integer - description: The resource's automatically generated unique identifier - name: - type: string - minLength: 1 - description: '' - created_at: - type: string - minLength: 1 - description: '' - format: date-time - updated_at: - type: string - minLength: 1 - description: '' - format: date-time - deleted_at: - type: - - string - - 'null' - minLength: 1 - description: '' - format: date-time - Link: - title: Link - type: object - properties: - id: - type: integer - link: - type: string - format: hostname - title: - type: string - description: - type: string - auhtor_name: - type: string - author_email: - type: string - format: email - cover_image: - type: string - format: uri - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - deleted_at: - type: - - string - - 'null' - format: date-time - x-tags: - - Resources - - Links - description: A Link resource's details - Pagination: - title: Pagination - type: object - description: Default pagination structure - x-tags: - - Structures - - Pagination - properties: - first: - type: string - description: First page url - format: uri - prev: - type: - - string - - 'null' - description: Previous page url - format: uri - next: - type: - - string - - 'null' - description: Next page url - format: uri - Error: - title: Error - type: object - description: Default error structure - properties: - errors: - type: array - description: An array of key/value pairs where key is the input that failed on validation and the value is a formatted detail message of the error - uniqueItems: true - items: {} - x-tags: - - Structures - - Errors - User: - title: User - type: object - description: A User resource's details - x-tags: - - Resources - - Users - properties: - id: - type: integer - description: The resource's automatically generated unique identifier - name: - type: string - email: - type: string - format: email - trusted: - type: boolean - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - deleted_at: - type: - - string - - 'null' - format: date-time - securitySchemes: - ' Bearer Token': - type: http - scheme: bearer - description: '' -security: [] -tags: - - name: Links - - name: Tags - - name: Accounts - - name: Discussions - - name: Questions - - name: Login - - name: Logout - - name: Users - - name: Answers